Perlbmk Bigint

From Msim

Jump to: navigation, search

In the Spec2K benchmark suite, the reference test for perlbmk (perfect.pl b 3 m 4) does not simulate correctly.

The Problem

In lib/Math/BigInt.pm, the use of an integer cast may round up.

$x * 1e-5, when $x is 66666. Generates 0.66666
int($x * 1e-5) should return 0, but, instead returns 1.

Note: This problem has only been observed the current M-sim release on a linux machine. Prior M-sim releases and simplesim-3.0d never finished termination either but we never actually verified that the same problem existed. In lib/Math/BigInt.pm::sub bdiv - Original Code

if (($dd = int(1e5/($y[$#y]+1))) != 1) {
 for $x (@x) {
  $x = $x * $dd + $car;
  $x -= ($car = int($x * 1e-5)) * 1e5;
 }
 push(@x, $car); $car = 0;
 for $y (@y) {
  $y = $y * $dd + $car;
  $y -= ($car = int($y * 1e-5)) * 1e5;
 }
}
...
if ($q) {
 ($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;
  $x[$x] += 1e5 if ($bar = (($x[$x] -= $prd + $bar) < 0));
 }

We replace with the following (see bolded sections):

if (($dd = int(1e5/($y[$#y]+1))) != 1) {
 for $x (@x) {
  $x = $x * $dd + $car;
  $adjusted = $x * 1e-5;
  $x -= ($car = (int($adjusted) > $adjusted) ? int($adjusted) - 1 : int($adjusted)) * 1e5;
 }
 push(@x, $car); $car = 0;
 for $y (@y) {
  $y = $y * $dd + $car;
  $adjusted = $y * 1e-5;
  $y -= ($car = (int($adjusted) > $adjusted) ? int($adjusted) - 1 : int($adjusted)) * 1e5;
 }
}
...
if ($q) {
 ($car, $bar) = (0,0);
 for ($y = $[, $x = $#x-$#y+$[-1; $y <= $#y; ++$y,++$x) {
  $prd = $q * $y[$y] + $car;
  $adjusted = $prd * 1e-5;
  $prd -= ($car = (int($adjusted) > $adjusted) ? int($adjusted) - 1 : int($adjusted)) * 1e5;
  $x[$x] += 1e5 if ($bar = (($x[$x] -= $prd + $bar) < 0));
 }


Patch

Applying the changes shown in bold above will allow this reference test to complete on M-sim. In short, the changes check if the integer cast made the number larger. If the number is larger after an integer cast (this never should happen), subtract 1.

Personal tools