#!/usr/bin/env perl
use strict;
use warnings;
use Test::More;
use Math::Prime::Util::GMP qw/logreal expreal powreal agmreal/;
my $extra = defined $ENV{EXTENDED_TESTING} && $ENV{EXTENDED_TESTING};
# gp: \p 71 for(s=1,20,print(log(s/10)))
my @log_pos = (qw/
-2.3025850929940456840179914546843642076011014886287729760333279009675726
-1.6094379124341003746007593332261876395256013542685177219126478914741790
-1.2039728043259359926227462177618385029536109308060235242986335673300783
-0.91629073187415506518352721176801107145010121990826246779196788198078537
-0.69314718055994530941723212145817656807550013436025525412068000949339362
-0.51082562376599068320551409630366193487811079644576827017795355783668469
-0.35667494393873237891263871124118447796401675904691178757393775102999275
-0.22314355131420975576629509030983450337460108554800721367128787248739174
-0.10536051565782630122750098083931279830612037298327407256393923369258402
0.00000000000000000000000000000000000000000000000000000000000000000000000
0.09531017980432486004395212328076509222060536530864419918523980816300101
0.18232155679395462621171802515451463319738933791448698394272645165670893
0.26236426446749105203549598688095439720416645613143414038571760969589206
0.33647223662121293050459341021699209011148337531334346654674225846340088
0.40546510810816438197801311546434913657199042346249419761401432414410067
0.47000362924573555365093703114834206470089904881224804044939213700600188
0.53062825106217039623154316318876232798710152395697181126390983691471997
0.58778666490211900818973114061886376976937976137698118155674077580080960
0.64185388617239477599103597720348932963627777267035584250463233544172009
0.69314718055994530941723212145817656807550013436025525412068000949339362
/);
my @log_neg = (qw/
2.3025850929940456840179914546843642076011014886287729760333279009675726
1.6094379124341003746007593332261876395256013542685177219126478914741790
1.2039728043259359926227462177618385029536109308060235242986335673300783
0.91629073187415506518352721176801107145010121990826246779196788198078537
0.69314718055994530941723212145817656807550013436025525412068000949339362
0.51082562376599068320551409630366193487811079644576827017795355783668469
0.35667494393873237891263871124118447796401675904691178757393775102999275
0.22314355131420975576629509030983450337460108554800721367128787248739174
0.10536051565782630122750098083931279830612037298327407256393923369258402
0.00000000000000000000000000000000000000000000000000000000000000000000000
-0.09531017980432486004395212328076509222060536530864419918523980816300101
-0.18232155679395462621171802515451463319738933791448698394272645165670893
-0.26236426446749105203549598688095439720416645613143414038571760969589206
-0.33647223662121293050459341021699209011148337531334346654674225846340088
-0.40546510810816438197801311546434913657199042346249419761401432414410067
-0.47000362924573555365093703114834206470089904881224804044939213700600188
-0.53062825106217039623154316318876232798710152395697181126390983691471997
-0.58778666490211900818973114061886376976937976137698118155674077580080960
-0.64185388617239477599103597720348932963627777267035584250463233544172009
-0.69314718055994530941723212145817656807550013436025525412068000949339362
/);
plan tests => 1+2+2+3 # logreal
+ 6 # expreal
+ 7 # powreal
+ 5 # agmreal
;
######## log
ok(!eval { logreal(0); }, "log(0)");
# Small around 1
is_deeply( [map { logreal($_/10,71) } 1 .. 20],
[ map { my $v=$_; $v=~s/^0\./\./; $v=~s/^-0\./-\./; $v; } @log_pos ],
"log(0.1, 0.2, ..., 2.0) with 71 digits" );
is_deeply( [map { logreal(-$_/10,71) } 1 .. 20],
[ map { my $v=$_; $v=~s/^0\./\./; $v=~s/^-0\./-\./; $v; } @log_neg ],
"log(-0.1, -0.2, ..., -2.0) with 71 digits" );
is(logreal(2,200),
'.69314718055994530941723212145817656807550013436025525412068000949339362196969471560586332699641868754200148102057068573368552023575813055703267075163507596193072757082837143519030703862389167347112335',
"logreal(2,200)");
is(logreal("1"."0"x1000,200),
'2302.5850929940456840179914546843642076011014886287729760333279009675726096773524802359972050895982983419677840422862486334095254650828067566662873690987816894829072083255546808437998948262331985283935',
"logreal(10^1000,200)");
is(logreal(5,71),'1.6094379124341003746007593332261876395256013542685177219126478914741790',"logreal(5,71)");
is(logreal(10,71),'2.3025850929940456840179914546843642076011014886287729760333279009675726',"logreal(10,71)");
is(logreal(21,71),'3.0445224377234229965005979803657054342845752874046106401940844835750742',"logreal(21,71)");
######## exp
is(expreal(1,71),'2.7182818284590452353602874713526624977572470936999595749669676277240766',"expreal(1,71)");
is(expreal(12.5,71),'268337.28652087445695647967378715040272579062274906405277947593333627473',"expreal(12.5,71)");
is(expreal(100,71),'26881171418161354484126255515800135873611118.773741922415191608615280287',"expreal(100,71)");
is(expreal(100,12),'268811714182E32',"expreal(100,12)");
is(expreal(-118.5,71),'.00000000000000000000000000000000000000000000000000034364014567198602057',"expreal(-118.5,71)");
is(expreal("-394.84010945715266885",200),'.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000033351796227864913872998321605',"expreal(-394.84010945715266885,200)");
######## pow
is(powreal(0,2.2,20),'.00000000000000000000',"powreal(0,2.2,20)");
is(powreal(1,2.2,20),'1.0000000000000000000',"powreal(1,2.2,20)");
is(powreal(-1,2.2,20),'-1.0000000000000000000',"powreal(-1,2.2,20)");
is(powreal(2,-5.01,60),'.031034140482407371922912819277752330350669761418765540014674',"powreal(2,-5.01,60)");
is(powreal(2,5,2),32,"powreal(2,5,2)");
is(powreal(2,-5,5),".03125","powreal(2,-5,5)");
is(powreal(1234.5678, 9.87654321, 60),
"3415709626357388739894539947448.87170455872193676278327545082",
"powreal(1234.5678, 9.87654321, 60)");
######## agm
is(agmreal(1,'1.4142135623730950488016887242096980785696718753769480731766797379907325',71),
'1.1981402347355922074399224922803238782272126632156515582636749529464052',
"AGM(1, sqrt(2)) = reciprocal of Gauss's constant");
is(agmreal(1,'0.707106781186547524400844362104849039284835937688474036588339868995366239',72),
'.847213084793979086606499123482191636481445910326942185060579372659734005',
"AGM(1, 1/sqrt(2))");
is(agmreal(0.5,1,71),
'.72839551552345343459321619163254098748693197161065279539708619163396323',
"AGM(0.5, 1)");
is(agmreal(6,24,30),
'13.4581714817256154207668131570',
"AGM(6, 24)");
is(agmreal(-6,24,30),
undef,
"AGM with negative argument returns undef");