develooper Front page | perl.perl5.porters | Postings from January 2001

[PATCH: perl@8342] lib/bigfloat.t FAILED at test 351

From:
Roca, Ignasi
Date:
January 10, 2001 06:51
Subject:
[PATCH: perl@8342] lib/bigfloat.t FAILED at test 351
Message ID:
5930DC161690D2119667009027157547037E2B25@madt009a.siemens.es
As I can see perl in VMS fails like in POSIX-BC on test 351 of test-script
lib/bigfloat.t
 
In POSIX-BC the /390-Arithmetic-Floating-Point implementation has some
imprecisse results that affects the C-Math functions.
Here an example:

#include <math.h>

main()
{
double r,s,t;

printf ("\n<<< r = 800000.0 * 1e-5 >>>\n");
r = 800000.0 * 1e-5;
t = modf (r,&s);
printf("r=%e, s=%e, t=%e\n",r,s,t);

printf ("\n<<< r = 800000.0 / 1e+5 >>>\n");
r = 800000.0 / 1e+5;
t = modf (r,&s);
printf("r=%e, s=%e, t=%e\n",r,s,t);
}


The result in POSIX-BC as unexpected is the following:
<<< r = 800000.0 * 1e-5 >>>
r=8.000000e+00, s=7.000000e+00, t=1.000000e+00

<<< r = 800000.0 / 1e+5 >>>
r=8.000000e+00, s=8.000000e+00, t=0.000000e+00


Perl's sqrt() function fails due to this Arithmetic-Floating-Point problem.
As I'm not able to use another floating-point implementation which was ieee
compliant, I found a way to solve the problem of sqrt(), following there is
a patch that corrects the sqrt problem:

=========================================================
--- bigint.pl.orig      Tue Dec 12 04:30:51 2000
+++ bigint.pl   Wed Jan 10 14:54:27 2001
@@ -213,7 +213,7 @@
            for $y (@y) {
                $prod = $x * $y + $prod[$cty] + $car;
                $prod[$cty++] =
-                   $prod - ($car = int($prod * 1e-5)) * 1e5;
+                   $prod - ($car = int($prod / 1e5)) * 1e5;
            }
            $prod[$cty] += $car if $car;
            $x = shift @prod;
@@ -239,12 +239,12 @@
     if (($dd = int(1e5/($y[$#y]+1))) != 1) {
        for $x (@x) {
            $x = $x * $dd + $car;
-           $x -= ($car = int($x * 1e-5)) * 1e5;
+           $x -= ($car = int($x / 1e5)) * 1e5;
        }
        push(@x, $car); $car = 0;
        for $y (@y) {
            $y = $y * $dd + $car;
-           $y -= ($car = int($y * 1e-5)) * 1e5;
+           $y -= ($car = int($y / 1e5)) * 1e5;
        }
     }
     else {
@@ -259,7 +259,7 @@
            ($car, $bar) = (0,0);
            for ($y = $[, $x = $#x-$#y+$[-1; $y <= $#y; ++$y,++$x) {
                $prd = $q * $y[$y] + $car;
-               $prd -= ($car = int($prd * 1e-5)) * 1e5;
+               $prd -= ($car = int($prd / 1e5)) * 1e5;
                $x[$x] += 1e5 if ($bar = (($x[$x] -= $prd + $bar) < 0));
            }
            if ($x[$#x] < $car + $bar) {
=========================================================
--- BigInt.pm.orig	Tue Dec 12 04:30:46 2000
+++ BigInt.pm	Wed Jan 10 14:49:37 2001
@@ -229,7 +229,7 @@
       for $y (@y) {
 	$prod = $x * $y + ($prod[$cty] || 0) + $car;
 	$prod[$cty++] =
-	  $prod - ($car = int($prod * 1e-5)) * 1e5;
+	  $prod - ($car = int($prod / 1e5)) * 1e5;
       }
       $prod[$cty] += $car if $car;
       $x = shift @prod;
@@ -254,12 +254,12 @@
     if (($dd = int(1e5/($y[$#y]+1))) != 1) {
 	for $x (@x) {
 	    $x = $x * $dd + $car;
-	    $x -= ($car = int($x * 1e-5)) * 1e5;
+	    $x -= ($car = int($x / 1e5)) * 1e5;
 	}
 	push(@x, $car); $car = 0;
 	for $y (@y) {
 	    $y = $y * $dd + $car;
-	    $y -= ($car = int($y * 1e-5)) * 1e5;
+	    $y -= ($car = int($y / 1e5)) * 1e5;
 	}
     }
     else {
@@ -276,7 +276,7 @@
 	    ($car, $bar) = (0,0);
 	    for ($y = $[, $x = $#x-$#y+$[-1; $y <= $#y; ++$y,++$x) {
 		$prd = $q * $y[$y] + $car;
-		$prd -= ($car = int($prd * 1e-5)) * 1e5;
+		$prd -= ($car = int($prd / 1e5)) * 1e5;
 		$x[$x] += 1e5 if ($bar = (($x[$x] -= $prd + $bar) < 0));
 	    }
 	    if ($x[$#x] < $car + $bar) {
=========================================================



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About