Skip to content

Update Sum.php #4441

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft

Update Sum.php #4441

wants to merge 1 commit into from

Conversation

PavelZul
Copy link

@PavelZul PavelZul commented Apr 9, 2025

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
Copy link
Collaborator

oleibman commented Apr 9, 2025

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
Copy link
Collaborator

oleibman commented Apr 10, 2025

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
Copy link
Collaborator

oleibman commented Apr 10, 2025

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
Author

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

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