1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
|
use strict;
use warnings;
use Math::MPFR qw(:mpfr);
use Test::More;
if( MPFR_VERSION_MAJOR() < 4) {
warn " Skipping - these tests require mpfr-4.0.0\n or later, but we have only mpfr-",
MPFR_VERSION_STRING(), "\n";
ok('1' eq '1', "dummy test");
done_testing();
exit 0;
}
my @in = ('15400000000000000.0', '1.54e+16', '1107610000000000000.0', '1.10761e+18',
'13687000000000000.0', '1.3687e+16', '16800000000000000000.0','1.68e+19',
'11443200000000000000000000000.0', '1.14432e+28',
'0.0', '-0.0', 'NaN', '-NaN', 'Inf', '-Inf', '0.1', '0.3',
nvtoa(atonv('1.4') / 10));
Rmpfr_set_default_prec($Math::MPFR::NV_properties{bits});
if( $Math::MPFR::NV_properties{bits} == 2098 ) {
warn "Skipping tests that are not written for DoubleDouble nvtype. (TODO.)\n"
}
else {
push @in, ('128702000000000000000000000000000.0', '1.28702e+32');
}
for(@in) {
my $rop = Math::MPFR->new($_);
my $nv = Rmpfr_get_NV($rop, MPFR_RNDN);
my $s1 = mpfrtoa($rop);
my $s2 = nvtoa(atonv($_));
cmp_ok($s1, 'eq', $s2, "mpfrtoa() and nvtoa() agree for $_");
ok(dragon_test( $rop) == 15, "$_ passes dragontest (MPFR)"); # $s1
ok(dragon_test( $nv ) == 15, "$_ passes dragon test (NV)"); # $s2
}
##############################################################################
# Check that mpfrtoa(Math::MPFR::object) eq nvtoa(NV) eq Math::Ryu::nv2s(NV) #
# whenever: #
# a) the value of the Math::MPFR object and the NV are identical #
# && #
# b) the precision of the Math::MPFR object matches the precision of the NV. #
# Math::MPFR precision has already been set such that b) is satisfied. #
# The Math::Ryu::nv2s() check is dependent upon Math::Ryu being available. #
##############################################################################
my $have_ryu = 0;
eval{require Math::Ryu;};
$have_ryu = 1 if(!$@ && $Math::Ryu::VERSION >= 1.05);
for(1 .. 100) {
if($Math::MPFR::NV_properties{bits} == 2098) {
warn "Skipping additional tests also inapplicable to DoubleDouble nvtype. (TODO.)\n";
last;
}
my($e, $n, $digits, $s);
$e = int(rand(256));
$digits = int(Rmpfr_get_default_prec() * 0.3);
$n .= int(rand(10)) for 1..$digits;
$e *= -1 if $_ % 3;
$s = "1.${n}e${e}";
if($_ & 1) {
$s = '-' . $s;
}
my $f = Math::MPFR->new($s);
my $nv = Rmpfr_get_NV($f, MPFR_RNDN);
my $s1 = mpfrtoa($f);
my $s2 = nvtoa($nv);
cmp_ok($s1, 'eq', $s2, "mpfrtoa() and nvtoa() agree for $s");
ok(dragon_test( $f ) == 15, "$s passes dragon test (MPFR)"); # $s1
ok(dragon_test( $nv) == 15, "$s passes dragon test (NV)"); # $s2
if($have_ryu) {
my $s3 = Math::Ryu::nv2s($nv);
cmp_ok($s1, 'eq', $s3, "mpfrtoa() and Math::Ryu agree for $s");
}
}
###########################################################################
# Next we test that, for various values at various precisions (that don't #
# match any NV precisions), the result provided by mpfrtoa() is correct. #
###########################################################################
for my $prec( 20000, 2000, 200, 96, 21, 5 ) {
Rmpfr_set_default_prec( $prec );
for( 1 .. 100, '0.1', '0.10000000000000001', '0.3', nvtoa(1.4 / 10) ) {
my($e, $n, $digits, $s);
unless( $_ =~ /\./ ) {
$e = int(rand(2048));
$digits = int( Rmpfr_get_default_prec() / 5 );
$n .= int(rand( 10 )) for 1..$digits;
$e *= -1 if $_ % 3;
$s = "1${n}e${e}";
}
else {$s = "$_"}
my $sign = 0;
if( $_ & 1 ) {
$s = '-' . $s;
$sign = 1;
}
my $f = Math::MPFR->new( $s );
my $dec = mpfrtoa( $f );
ok(dragon_test($f) == 15, "$s passes dragon test (NV)");
}
}
done_testing;
|