Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

CC: increase numeric precision a bit

%g is a very poor choice to keep double precision, as it defaults to 6 digits.
double needs 16-17 digits, 16 usually the best.
Also note that the ops do not use NV as long double, even if d_longdbl is defined.
A NV is double.

%.16g is enough precision to pass the shootout nbody test.
  • Loading branch information...
commit 3fc61aa69af24d438a2983a15996362207443f43 1 parent 61f4f1a
@rurban authored
Showing with 16 additions and 11 deletions.
  1. +5 −0 lib/B/C.pm
  2. +11 −11 lib/B/CC.pm
View
5 lib/B/C.pm
@@ -810,6 +810,11 @@ sub nvx ($) {
my $dblmax = "1.79769313486232e+308";
# my $ldblmax = "1.18973149535723176502e+4932L"
my $ll = $Config{d_longdbl} ? "LL" : "L";
+ if ($nvgformat eq 'g') { # a very poor choice to keep precision
+ # on intel 17-18, on ppc 31, on sparc64/s390 34
+ # $nvgformat = $Config{d_longdbl} ? '.17Lg' : '.16g';
+ $nvgformat = '.16g'; # typedef double NV
+ }
my $sval = sprintf("%${nvgformat}%s", $nvx, $nvx > $dblmax ? $ll : "");
if ($nvx < -$dblmax) {
$sval = sprintf("%${nvgformat}%s", $nvx, $ll);
View
22 lib/B/CC.pm
@@ -1041,10 +1041,10 @@ sub declare_pad {
declare( "IV",
$type == T_INT ? sprintf( "%s=0", $pad[$ix]->{iv} ) : $pad[$ix]->{iv} )
if $pad[$ix]->save_int;
- declare( "double",
+ declare( "NV",
$type == T_DOUBLE
- ? sprintf( "%s = 0", $pad[$ix]->{nv} )
- : $pad[$ix]->{nv} )
+ ? sprintf( "%s = 0", $pad[$ix]->{nv} )
+ : $pad[$ix]->{nv} )
if $pad[$ix]->save_double;
}
@@ -1732,7 +1732,7 @@ sub numeric_binop {
);
}
else {
- my $rightruntime = B::Pseudoreg->new( "double", "rnv" );
+ my $rightruntime = B::Pseudoreg->new( "NV", "rnv" );
runtime( sprintf( "$$rightruntime = %s;\t/* %s */", $right, $op->name ) );
runtime(
sprintf(
@@ -1754,8 +1754,8 @@ sub numeric_binop {
$targ->set_int( &$operator( $$left, $$right ) );
}
else {
- my $right = B::Pseudoreg->new( "double", "rnv" );
- my $left = B::Pseudoreg->new( "double", "lnv" );
+ my $right = B::Pseudoreg->new( "NV", "rnv" );
+ my $left = B::Pseudoreg->new( "NV", "lnv" );
runtime(
sprintf( "$$right = %s; $$left = %s;\t/* %s */",
pop_numeric(), pop_numeric, $op->name ) );
@@ -1787,7 +1787,7 @@ sub pp_ncmp {
runtime "}";
}
else {
- my $rightruntime = B::Pseudoreg->new( "double", "rnv" );
+ my $rightruntime = B::Pseudoreg->new( "NV", "rnv" );
runtime( sprintf( "$$rightruntime = %s;\t/* %s */", $right, $op->name ) );
runtime sprintf( qq/if ("TOPn" > %s){/, $rightruntime );
runtime sprintf(" sv_setiv(TOPs,1);");
@@ -1802,8 +1802,8 @@ sub pp_ncmp {
}
else {
my $targ = $pad[ $op->targ ];
- my $right = B::Pseudoreg->new( "double", "rnv" );
- my $left = B::Pseudoreg->new( "double", "lnv" );
+ my $right = B::Pseudoreg->new( "NV", "rnv" );
+ my $left = B::Pseudoreg->new( "NV", "lnv" );
runtime(
sprintf( "$$right = %s; $$left = %s;\t/* %s */",
pop_numeric(), pop_numeric, $op->name ) );
@@ -1898,8 +1898,8 @@ sub bool_int_binop {
# coverage: ?
sub bool_numeric_binop {
my ( $op, $operator ) = @_;
- my $right = B::Pseudoreg->new( "double", "rnv" );
- my $left = B::Pseudoreg->new( "double", "lnv" );
+ my $right = B::Pseudoreg->new( "NV", "rnv" );
+ my $left = B::Pseudoreg->new( "NV", "lnv" );
runtime(
sprintf( "$$right = %s; $$left = %s;\t/* %s */",
pop_numeric(), pop_numeric(), $op->name ) );
Please sign in to comment.
Something went wrong with that request. Please try again.