Skip to content

Commit e4ce0ea

Browse files
committed
Floating Point and Php Nightly 8.4
Fix PHPOffice#3896. It appears that floating-point arithmetic will give different results in Php 8.4 vs. all earlier releases. This causes tests to fail in the nightly run for ROUNDDOWN, ROUNDUP, and AMORDEGRC. I imagine this won't be the last we hear of this. The failures are a distraction when reviewing PR's. This PR eliminates the distraction by adding in a fudge factor for Php 8.4+ while not changing Php 8.3-. It is not a particularly robust solution, but it should be stable for Php 8.3-, and good enough for Php 8.4+ while I study if a better solution is available.
1 parent a444d1c commit e4ce0ea

File tree

2 files changed

+9
-4
lines changed

2 files changed

+9
-4
lines changed

src/PhpSpreadsheet/Calculation/Financial/Amortization.php

+3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
class Amortization
1111
{
12+
private const ROUNDING_ADJUSTMENT = (PHP_VERSION_ID < 80400) ? 0 : 1e-14;
13+
1214
/**
1315
* AMORDEGRC.
1416
*
@@ -80,6 +82,7 @@ public static function AMORDEGRC(
8082
$amortiseCoeff = self::getAmortizationCoefficient($rate);
8183

8284
$rate *= $amortiseCoeff;
85+
$rate += self::ROUNDING_ADJUSTMENT;
8386
$fNRate = round($yearFrac * $rate * $cost, 0);
8487
$cost -= $fNRate;
8588
$fRest = $cost - $salvage;

src/PhpSpreadsheet/Calculation/MathTrig/Round.php

+6-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ class Round
1010
{
1111
use ArrayEnabled;
1212

13+
private const ROUNDING_ADJUSTMENT = (PHP_VERSION_ID < 80400) ? 0 : 1e-14;
14+
1315
/**
1416
* ROUND.
1517
*
@@ -68,10 +70,10 @@ public static function up($number, $digits): array|string|float
6870
}
6971

7072
if ($number < 0.0) {
71-
return round($number - 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_DOWN);
73+
return round($number - 0.5 * 0.1 ** $digits + self::ROUNDING_ADJUSTMENT, $digits, PHP_ROUND_HALF_DOWN);
7274
}
7375

74-
return round($number + 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_DOWN);
76+
return round($number + 0.5 * 0.1 ** $digits - self::ROUNDING_ADJUSTMENT, $digits, PHP_ROUND_HALF_DOWN);
7577
}
7678

7779
/**
@@ -104,10 +106,10 @@ public static function down($number, $digits): array|string|float
104106
}
105107

106108
if ($number < 0.0) {
107-
return round($number + 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_UP);
109+
return round($number + 0.5 * 0.1 ** $digits - self::ROUNDING_ADJUSTMENT, $digits, PHP_ROUND_HALF_UP);
108110
}
109111

110-
return round($number - 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_UP);
112+
return round($number - 0.5 * 0.1 ** $digits + self::ROUNDING_ADJUSTMENT, $digits, PHP_ROUND_HALF_UP);
111113
}
112114

113115
/**

0 commit comments

Comments
 (0)