File: mpfrtoa.t

package info (click to toggle)
libmath-mpfr-perl 4.45-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,716 kB
  • sloc: perl: 1,508; ansic: 517; makefile: 9
file content (122 lines) | stat: -rwxr-xr-x 3,846 bytes parent folder | download | duplicates (2)
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;