PHP floating-point knowledge

Source: Internet
Author: User
Tags assert

This article mainly introduced you should know the PHP floating point knowledge, this article explained the PHP floating-point number, the PHP numerical critical value, the accuracy loss and so on question, needs the friend to be possible to refer to under

PHP is a weak type language, such a feature, inevitably requires a seamless and transparent implicit type conversion, PHP internal use Zval to save any type of value, Zval structure as follows (5.2 for example):

The code is as follows:

struct _zval_struct {

/* Variable Information * *

Zvalue_value value; /* Value * *

Zend_uint RefCount;

Zend_uchar type; /* Active type */

Zend_uchar Is_ref;

};

In the structure above, the actual save value is the Zvalue_value consortium:

The code is as follows:

typedef Union _ZVALUE_VALUE {

Long lval; /* Long Value * *

Double Dval; /* Double Value * *

struct {

Char *val;

int Len;

} str;

HashTable *ht; /* Hash Table value * *

Zend_object_value obj;

} Zvalue_value;

For today's topic, we are only interested in two of the members, Lval and Dval, and we realize that long lval is variable in length with the compiler, OS, and it can be 32bits or 64bits, and double dval (double precision) is regulated by IEEE 754 , is fixed long, must be 64bits.

Keep this in mind, creating a "non-platform-independent" of some of PHP's code. Our next discussion, except specifically, assumes long to be 64bits

IEEE 754 floating point counting method, I do not quote here, we are interested can see for themselves, the key point is that the mantissa of the double with 52 bit to save, calculate the hidden 1-bit effective bit, a total of 53bits.

Here, a very interesting question arises, we use the C code example (assuming Long is 64bits):

The code is as follows:

Long a = x;

assert (A = = (long) (double) a);

Excuse me, what is the value of a in the range of time, the above code can assert success? (Stay in the final solution of the article)

Now that we're back to the point, PHP needs to read the script and parse the script before executing a script, and it also contains the zval of the literal in the script, such as the following script:

The code is as follows:

  

$a = 9223372036854775807; 64-bit signed number maximum

$b = 9223372036854775808; Maximum Value +1

Var_dump ($a);

Var_dump ($b);

Output:

The code is as follows:

Int (9223372036854775807)

Float (9.22337203685E+18)

Also say, PHP in the lexical analysis stage, for a literal value, will be judged, whether the current system is beyond the range of LONG table values, if not, then use Lval to save, zval for Is_long, otherwise the dval said, Zval is_float.

All values greater than the largest integer value, we should be careful, because it may have a loss of precision:

The code is as follows:

  

$a = 9223372036854775807;

$b = 9223372036854775808;

Var_dump ($a = = = ($b-1));

The output is false.

Now, with the discussion at the beginning, previously said, PHP's integer, may be 32 bits, or maybe 64 bits, then decided that some of the 64-bit can run normal code, may be due to stealth type conversion, the loss of precision, resulting in the code is not normal to run on the 32-bit system.

So, we have to be wary of this threshold, but in PHP we have already defined this threshold:

The code is as follows:

  

Echo Php_int_max;

?>

Of course, to be safe, we should use strings to hold large integers, and use mathematical libraries such as bcmath to compute.

In addition, there is a key configuration, will let us create confusion, this configuration is php.precision, this configuration determines the PHP output a float value, the output of how many significant bits.

Finally, we look back at the question raised above, that is, a long integer, the maximum value is how much, to ensure that go to float and then back to long does not occur precision loss?

For example, for integers, we know that its binary representation is, 101, now, let's move to the right two digits, to 1.01, to the implied valid bit 1 of the high, and we get the binary value of storing 5 in double as:

The code is as follows:

0/* sign/10000000001/* digit */0100000000000000000000000000000000000000000000000000

The binary of 5 indicates that the slightest loss is saved in the tail part, in which case the transfer from double back to long does not occur without precision loss.

We know that Double uses 52 digits for the mantissa, which is the implied first 1, with a total of 53-bit precision. Then it can be concluded that if a long integer, the value is less than:

The code is as follows:

2^53-1 = 9007199254740991; Remember, we now assume that the 64bits long

So, this integer, in the event of a long->double->long numeric conversion, does not occur when the precision is lost.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.