Asked  1 Year ago    Answers:  5   Viewed   7 times

I just read an interesting article about php hanging on certain float numbers, see The Register and Exploring Binary.

I never explicitly use floats, I use number_format() to clean my input and display for example prices.

Also, as far as I am aware, all input from for example forms are strings until I tell them otherwise so I am supposing that this problem does not affect me.

Am I right, or do I need to check for example Wordpress and Squirrelmail installations on my server to see if they cast anything to float? Or better, grep all php files on my servers for float?



Ways to mitigate the problem:

  1. Use a modern CPU. Most modern 64-bit CPUs would be immune (I actually had trouble finding host that allows to reproduce it since they tend to use more modern hardware). Amazon VMs seem to be immune too.
  2. Upgrade your PHP version - 5.3.5 and 5.2.17 once released (probably today) include the fix.
  3. Build with -ffloat-store in CFLAGS (will slow down the code).
  4. Manually apply the patch to your code and rebuild PHP.

Looking for the code that has float probably won't help as zend_strtod is used by the engine in many string->number conversion scenarios.

P.S. this code btw is standard BSD library strtod code, not unique to PHP. So other projects using this code might be affected too.

Thursday, April 1, 2021

You can do this with this:

while($row = mysql_fetch_array($result)) 
  echo "<tr>"; 
  echo "<td>" . $row['CustomerID'] . "</td>"; 
  echo "<td>" . $row['CustomerName'] . "</td>"; 
  if($row['ProspectStatus']=='[val1]') // [val1] can be 'approved'
         echo "<td style='background-color: #00FF00;'>".$row['ProspectStatus']."</td>"; 
  else if($row['ProspectStatus']=='[val2]')// [val2]can be 'rejected'
         echo "<td style='background-color: #FF0000;'>".$row['ProspectStatus']."</td>"; 
  else if($row['ProspectStatus']=='[val3]') //[val3] can be 'on hold'
         echo "<td style='background-color: #FFFF00;'>".$row['ProspectStatus']."</td>"; 
  echo "<td>" . $row['Address'] . "</td>"; 
  echo "</tr>"; 
echo "</table>";  

The value of the status may depend on the color. I assume that val1, val2 and val3 are the values of the 3 colors.

Thursday, April 1, 2021

This is a bug in the symfony/var-dumper package when using PHP7.1. It was fixed in version 2.7.16, 2.8.9, 3.0.9 and 3.1.3. See the pull request:

In my case, I needed to composer update my laravel framework packages, as my vendor directory copy of that package was at 2.7.9. (I'm using Laravel 5.1; later versions use 2.8 and 3.0 of symfony, which also had the bug)

Saturday, May 29, 2021

You aren't doing anything wrong. Floats are notoriously innaccurate. From the docs (In the huge red warning box):

Floating point numbers have limited precision. Although it depends on the system, PHP typically uses the IEEE 754 double precision format, which will give a maximum relative error due to rounding in the order of 1.11e-16. Non elementary arithmetic operations may give larger errors, and, of course, error propagation must be considered when several operations are compounded.

Additionally, rational numbers that are exactly representable as floating point numbers in base 10, like 0.1 or 0.7, do not have an exact representation as floating point numbers in base 2, which is used internally, no matter the size of the mantissa. Hence, they cannot be converted into their internal binary counterparts without a small loss of precision. This can lead to confusing results: for example, floor((0.1+0.7)*10) will usually return 7 instead of the expected 8, since the internal representation will be something like 7.9999999999999991118....

So never trust floating number results to the last digit, and do not compare floating point numbers directly for equality. If higher precision is necessary, the arbitrary precision math functions and gmp functions are available.

Saturday, July 31, 2021

Example 1

Those values will be the same -- you assign the same decimal literal to each variable. Compare that to this code:

$num1 = 27.64;
$num2 = 10.0 + 2.88 + 2.88 + 2.88 + 9.0; //In decimal arithmetic adds to 27.64

if ($num1 == $num2) {
    echo 'Good!';
} else {
    echo 'Bad!';

// Echo's "Bad!"

$num2 looks like it should be 27.64, but it really adds to something like 27.639999999999997015720509807579219341278076171875 (that's what I get when I do that calculation in Visual C++ on my machine). $num1 = 27.6400000000000005684341886080801486968994140625 (on my machine), so they differ.

Example 2

The trailing 0 makes no difference.

Example 3

The numbers are not within the floating-point "tolerance" so of course will differ.

Example 4

12.5 is exactly representable in floating point, so 12.5 + 12.5 is too (0.5 is 2^-1).

Thursday, December 30, 2021
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :