Skip to content

Update Sum.php#4441

Closed
PavelZul wants to merge 1 commit into
PHPOffice:masterfrom
PavelZul:patch-1
Closed

Update Sum.php#4441
PavelZul wants to merge 1 commit into
PHPOffice:masterfrom
PavelZul:patch-1

Conversation

@PavelZul

@PavelZul PavelZul commented Apr 9, 2025

Copy link
Copy Markdown

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).

This is:

  • a bugfix

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).
@oleibman

oleibman commented Apr 9, 2025

Copy link
Copy Markdown
Collaborator

Sorry, this will probably not be implemented. You are hitting too small a target in a game of whack-a-mole. Your fix works fine for:

SUM(A1:B1)=SUM(C1,D1)

It does nothing for:

(A1+B1)=(C1+D1)

And if you patch that, there are many other possibilities which will continue to fail.

There are risks in using floating-point. These are well documented in the Php manual, and manuals for most other languages. If you want to compare floats, you'll have to take precautions. For example, your cell formulas could use the following:

ROUND(SUM(A1:B1),5)=ROUND(SUM(C1:D1),5)
or
ABS(SUM(A1:B1)-SUM(C1:D1)) < 0.00001

(Where 5 and 0.00001 are, of course, totally arbitrary choices.)

@oleibman

oleibman commented Apr 10, 2025

Copy link
Copy Markdown
Collaborator

Now that I think about it, your problem really isn't with the SUM function, it is with the = operator. Perhaps it might be possible to introduce a 'tolerance' property to Calculation and use that when testing numerics for (in)equality. I will give that some thought.

@oleibman

oleibman commented Apr 10, 2025

Copy link
Copy Markdown
Collaborator

There is already a tolerance (0.1E-12) built into comparison operations, so no need for a change. I will, however, add that, because of this already existing constant, I do not duplicate your results:

$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->getCell('A1')->setValue(1.1);
$sheet->getCell('B1')->setValue(2.7);
$sheet->getCell('C1')->setValue(1.8);
$sheet->getCell('D1')->setValue(2);
$sheet->getCell('E1')->setValue('= IF(SUM(A1:B1) = SUM(C1:D1), "true", "false")');
var_dump($sheet->getCell('E1')->getCalculatedValue());

My result:

string(4) "true"

Do you get a different result with this code? If so, please let me know Php and PhpSpreadsheet versions.

@oleibman oleibman marked this pull request as draft April 13, 2025 22:07
@PavelZul

Copy link
Copy Markdown
Author

Have a great day! I'll check it on my side and send you an exact example a bit later.

@oleibman

Copy link
Copy Markdown
Collaborator

No update in 3 months, unable to duplicate problem, closing.

@oleibman oleibman closed this Jul 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants