From 50808563167d680934ef117b3fead4440ce307a1 Mon Sep 17 00:00:00 2001 From: Pavel Zhulidov <96257569+PavelZul@users.noreply.github.com> Date: Thu, 10 Apr 2025 00:03:36 +0400 Subject: [PATCH] Update Sum.php We have a cell in the example.xlsx sheet containing a total sum as a formula: E1 = IF(SUM(A1:B1) = SUM(C1:D1), "true", "false"), where: A1 = 1.1, B1 = 2.7, C1 = 1.8, D1 = 2. We expect the calculation result to be E1 = "true", but instead, we get E1 = "false" because in PHP, the addition yields: 1.1 + 2.7 = 3.8000000000000003, 1.8 + 2 = 3.8. The idea of the fork is to accept an input parameter specifying the number of decimal places and round the final sum to that precision before comparison. Additional Notes: This issue arises due to floating-point precision errors in programming languages like PHP. A possible solution is to use rounding (e.g., round(SUM(A1:B1), N) == round(SUM(C1:D1), N) where N is the desired decimal precision). --- src/PhpSpreadsheet/Calculation/MathTrig/Sum.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Sum.php b/src/PhpSpreadsheet/Calculation/MathTrig/Sum.php index f939d9e747..e32f63fe68 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Sum.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/Sum.php @@ -47,12 +47,19 @@ public static function sumIgnoringStrings(mixed ...$args): float|int|string */ public static function sumErroringStrings(mixed ...$args): float|int|string|array { - $returnValue = 0; + $returnValue = $maxDecimals = 0; // Loop through the arguments $aArgs = Functions::flattenArrayIndexed($args); foreach ($aArgs as $k => $arg) { // Is it a numeric value? if (is_numeric($arg)) { + // We count the number of signs after aim + $parts = explode('.', (string)$arg); + if (isset($parts[1])) { + $decimals = strlen(rtrim($parts[1], '0')); + $maxDecimals = max($maxDecimals, $decimals); + } + $returnValue += $arg; } elseif (is_bool($arg)) { $returnValue += (int) $arg; @@ -64,7 +71,10 @@ public static function sumErroringStrings(mixed ...$args): float|int|string|arra } } - return $returnValue; + return $maxDecimals + ? round($returnValue, $maxDecimals) + : $returnValue; + } /**