php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78492 Comparing Value from equation to 100
Submitted: 2019-09-04 14:30 UTC Modified: 2019-09-04 17:35 UTC
From: email at brunofaria dot pt Assigned: cmb (profile)
Status: Not a bug Package: *Math Functions
PHP Version: 7.3.9 OS: Windows 10
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: email at brunofaria dot pt
New email:
PHP Version: OS:

 

 [2019-09-04 14:30 UTC] email at brunofaria dot pt
Description:
------------
I'm adding this numbers from an array with key[0]: 

array(4) { [0]=> array(2) { [0]=> string(4) "61.8" [1]=> string(11) " Poliéster" } [1]=> array(2) { [0]=> string(4) "20.1" [1]=> string(6) " Nylon" } [2]=> array(2) { [0]=> string(4) "11.4" [1]=> string(9) " Algodão" } [3]=> array(2) { [0]=> string(3) "6.7" [1]=> string(6) " Rayon" } } 

61.8 + 20.1 + 11.4 + 6.7 = 100

Then I'm comparing to 100, 

Returns False.

Test script:
---------------
$value = 0;
foreach ($array as $key) {
  $value +=  floatval ( preg_replace ('/\s+/', '', $key[0]) ) ;
}

if ($value == 100 ) {
  return true;
} else {
  return false;
}

Expected result:
----------------
true

Actual result:
--------------
false

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-09-04 14:34 UTC] cmb@php.net
-Status: Open +Status: Not a bug -Assigned To: +Assigned To: cmb
 [2019-09-04 14:34 UTC] cmb@php.net
Floating point values have a limited precision. Hence a value might
not have the same string representation after any processing. That also
includes writing a floating point value in your script and directly
printing it without any mathematical operations.

If you would like to know more about "floats" and what IEEE
754 is, read this:
http://www.floating-point-gui.de/

Thank you for your interest in PHP.
 [2019-09-04 16:17 UTC] sinus at sinpi dot net
Rule #1: never compare floats with ==.
 [2019-09-04 17:35 UTC] email at brunofaria dot pt
Doesn't matter if its == or === always returns false.

Also, the result from the foreach loop is exactly '100' and I'm comparing to 100 , its the same string representation.
 [2019-09-04 17:47 UTC] email at brunofaria dot pt
I think I'm going to convert both values to strings and them compare them to work around this problem.
 [2019-09-04 17:58 UTC] phpbugreports at gmail dot com
convert to strings is sonsense even if it works by luck, limited precision was already explained, the value is something like "100.0000000000000142108547152020037174224853515625"

if(100 == (int)$value)
if(100 === (int)$value)

one of both would work

<?php
$value = 61.8 + 20.1 + 11.4 + 6.7;
ini_set('precision', 1000);
if(100 == (int)$value)
{
 echo "true: $value\n";
}
else
{
 echo "false: $value\n";
}
?>
 [2019-09-04 20:04 UTC] sinus at sinpi dot net
You should always compare floats with <, >, <= or >=. In your case, make it $value>99.999 and you'll be good.
 [2019-09-04 20:10 UTC] phpbugreports at gmail dot com
> You should always compare floats with <, >, <= or >=

for sure not

> In your case, make it $value>99.999 and you'll be good

even not for that isolated case because it would be >= 100 instead == 100 but not "99.9" with a random count of 9 added at the end

what you always should do is be as explicit as you can and > is the exact opposite, properly cast your values before compare and use === and !== where ever you can
 [2019-09-05 00:40 UTC] a at b dot c dot de
You should be checking that the result is within a range that depends on the accuracy of your numbers and what you're doing with them. In this case, adding numbers are accurate to one decimal place means that a result of 100 (strictly, 100.0) could in fact be anything between 99.95 and 100.05. (The real range won't be anywhere near that bad unless you're adding a LOT of numbers—in which case you maybe ought to change scale and work with integers—because the internal representation is much more precise than that.)

But it should be obvious that adding numbers with one-decimal-place accuracy will always produce a sum with one decimal place of accuracy, so any additional "accuracy" than that must therefore be a consequence of the approximations needed to represent all of the numbers involved with a fixed non-decimal precision.)

So in this case, you want to round the sum off two one digit of accuracy and then compare:

round(61.8 + 20.1 + 11.4 + 6.7, 1) == 100.0
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 15:01:29 2024 UTC