Real World PHP

About   |   EN   |   ES

006c Data Types: Floating Point Numbers

A floating point number type is any real number. We mostly call this type “float,” but we can also call them “double.” We can mostly use the two terms interchangeably, but float is, by far the most often used, and what we will use in these lessons. PHP was written in the C language. In C, there is a distinction: double is twice the size of float, but in PHP, they are both the same size and the keywords can be used interchangeably.

The following are some examples taken from the official PHP Documentation on Floating point numbers:

<?php
$a = 1.234; 
$b = 1.2e3; 
$c = 7E-10;
$d = 1_234.567; // as of PHP 7.4.0
?>

The size that your float can be depends on your system. Generally, the maximum is usually the 64-bit IEEE format. That is approximately 1.8e308 with a precision of 14 decimal digits.

Do not trust floats to the last digit and do not compare them directly for equality. There are other methods to handle those situations: bc math functions and gmp functions.

Converting to float from string

If the string is numeric, i.e. "3.1415," then it will convert perfectly. If the string is not numeric or doesn't begin with a number, i.e. "abc" or "tra 84.48," then it will convert to 0.

<?php
var_dump((float) "3.1415"); // float (3.1415)
var_dump((float) "3.14is PI"); // float(3.14)
var_dump((float) "XYZ"); // float(0)
var_dump((float) "LMNO 77.77"); // float(0)

// Note that these may display double() for you instead
// of float(). Remember, that in PHP, those are the same!
?>

Comparing floats

Note the warning above, but you can compare floats. As the documentation notes: "To test floating point values for equality, an upper bound on the relative error due to rounding is used. This value is known as the machine epsilon, or unit roundoff, and is the smallest acceptable difference in calculations."

<?php
$a = 1.23456789;
$b = 1.23456780;
$epsilon = 0.00001;

if(abs($a-$b) < $epsilon) {
    echo "true";
}
?>

We will cover comparison operators more in future lessons, but the thing to note here is the technique. Line 6 uses the function abs() which returns the absolute value of what is passed. Then it compares the difference to the unit roundoff (called $epsilon). This means that the two floats are the same up to 5 decimal places (in this example).

Special constant NaN

When doing floating point calculations, it is possible that you will sometimes get NaN (not a number) as a result. It is a special constant that represents an undefined or an undefinable value in floating point calculations. Anytime you compare NaN to anything, it will return false. Even if you compare it to itself! There is only one exception... if you compare it to true.

<?php
var_dump(NaN == 7); // false (compared to an int)
var_dump(NaN == 7.1); // false (compared to a float)
var_dump(NaN == "hello"); // false (compared to a string)
var_dump(NaN == null); // false
var_dump(NaN == false); // false
var_dump(NaN == NaN); // false

var_dump(NaN == true); // true
?>

It is important to understand these intricacies when working with floats.


Resources


Challenges

Floating Point Weirdness

Whenever you compare or manipulate floats in a computer, there is difficulty. This is because at the most basic level, the computer is storing a decimal number using binary. See for yourself by trying the following:

<?php
// Example 1
echo 0.7 - 0.2; // output: 0.5
var_dump(0.7 - 0.2 == 0.5); // output: false!

// Example 2 (for 64-bit systems)
echo 5.0 - 0.0000000000001; // output: 4.9999999999999
echo 5.0 - 0.00000000000001; // output: 5

// Example 3
var_dump(579.17 * 100); // output: double(57917)
var_dump((int) (579.17 * 100)); // output: int(57916)
?>