In PHP development, you often encounter this doubt: the results obtained by using the ceil() function look inconsistent with the results decoding after being serialized by json_encode() . Why does this phenomenon occur? This article will analyze the reasons from the perspectives of underlying numerical representation, JSON encoding mechanism, etc., and give corresponding examples.
The ceil() function is used to round upwards and returns the minimum integer value not less than the parameter. Its return value type is a float, and even if the result is an integer, the return value is still a floating point type.
<?php
$num = 4.2;
$result = ceil($num);
var_dump($result); // float(5)
?>
As you can see, ceil() returns a floating point number 5.0 , rather than an integer 5 .
Floating-point numbers in PHP are based on the IEEE 754 double precision standard and represent a number in 64-bit binary. Floating points cannot accurately represent all decimal decimals, and there is accuracy error.
This results in that even if the result of ceil() is theoretically an integer, such as 5.0 , there may be very small errors in the underlying binary storage.
json_encode() converts PHP's floating point numbers to JSON numeric types. JSON itself does not distinguish between integers and floating-point numbers, only numeric types.
For example:
<?php
$num = ceil(4.2);
$json = json_encode($num);
echo $json; // Output "5"
?>
Although $num is a floating point number 5.0 in PHP, it is represented as a number 5 in JSON, and the decimal point and decimal part are removed.
When you parse a JSON string using json_decode() , the number will be converted to floating point numbers or integers by default, depending on the representation of the JSON string.
<?php
$json = json_encode(ceil(4.2)); // "5"
$decoded = json_decode($json);
var_dump($decoded); // int(5)
?>
Here, json_decode() converts 5 in JSON into an integer int(5) , which is different from the floating point float(5) in the original PHP.
To sum up:
The return of ceil() is always a floating point number.
The number form output by json_encode() removes the decimal point part.
json_decode() converts it into integers or floating point numbers based on numeric forms.
Therefore, ceil() gets the floating point number float(5) , which may become an integer int(5) after JSON serialization and decoding.
This is why you see different results types and manifestations of the two.
<?php
$num = 4.2;
$ceilValue = ceil($num);
echo "ceil() result:";
var_dump($ceilValue); // float(5)
$json = json_encode($ceilValue);
echo "json_encode() result: $json\n"; // "5"
$decoded = json_decode($json);
echo "json_decode() result:";
var_dump($decoded); // int(5)
?>
Output:
ceil() result:float(5)
json_encode() result:5
json_decode() result:int(5)
If you want to keep the return value of ceil() as an integer type, you can cast the type after use:
$intValue = (int)ceil($num);
Pay attention to the automatic conversion of numeric types after JSON parsing. If necessary, you can turn on the second parameter $assoc = true to convert JSON into an associative array, which is more convenient to handle.
Understand the differences between floating-point numbers and JSON numbers, and avoid logical errors caused by different types.