You should know about PHP floating point and PHP floating point. _ PHP Tutorial

Source: Internet
Author: User
You should know about PHP floating point and PHP floating point. You should know about PHP floating point numbers. PHP floating point knowledge PHP is a weak language. such a feature requires seamless and transparent implicit type conversion, PHP internal use of zval to save any knowledge you should know about PHP floating point and PHP floating point

PHP is a weak type language, which requires seamless and transparent implicit type conversion. PHP uses zval to store any type of values, the structure of zval is as follows (5.2 is used as an 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 above structure, the zvalue_value consortium is actually saved for the value itself:
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;

In today's topic, we only focus on two of them, lval and dval. we need to realize that long lval varies with the compiler and OS length, it may be 32bits or 64 bits, while double dval (dual precision) is defined by IEEE 754, which is fixed length and must be 64bits.

Keep this in mind, and make some PHP code "non-platform-independent". In our next discussion, except for some specific instructions, we assume that long is 64 bits.

The floating point counting method of IEEE 754 is not referenced here. if you are interested, you can check it by yourself. The key point is that the ending number of double is saved in 52 bits, the hidden 1-bit valid bit. The total value is 53bits.

Here, a very interesting question is raised. We use the c code example (assuming that long is 64 bits ):
The code is as follows:
Long a = x;
Assert (a = (long) (double) );

When the value of a is within the scope, can the above code assert success? (Stay at the end of the article)

Now let's get back to the question. before executing a script, PHP needs to read the script and analyze the script. this process also includes zval for the literal volume in the script, for example, for the following script:
The code is as follows:
<? Php
$ A = 9223372036854775807; // maximum number of 64-bit signed characters
$ B = 9223372036854775808; // maximum value + 1
Var_dump ($ );
Var_dump ($ B );

Output:
The code is as follows:
Int (9223372036854775807)
Float (9.22337204255e + 18)

That is to say, in the lexical analysis phase of PHP, a literal value is determined to determine whether it exceeds the long table value range of the current system. if not, lval is used for saving. zval is IS_LONG. Otherwise, it is represented by dval, and zval IS_FLOAT.

Take care of any value greater than the largest integer, because it may cause loss of precision:
The code is as follows:
<? Php
$ A = 9223372036854775807;
$ B = 9223372036854775808;

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

The output is false.

Now let's start with the discussion. as we have said before, the PHP integer may be 32-bit or 64-bit, which determines that some code can run normally on 64-bit, this may cause loss of precision due to invisible type conversion, resulting in code failure to run on a 32-bit system.

Therefore, we must be aware of this critical value. Fortunately, this critical value has been defined in PHP:
The code is as follows:
<? Php
Echo PHP_INT_MAX;
?>

Of course, to be safe, we should use strings to store large integers and use mathematical libraries such as bcmath for calculation.

In addition, there is another key configuration that will confuse us. This configuration is php. precision, which determines how many valid bits are output when PHP outputs another float value.

Finally, let's look back at the above question, that is, a long integer. what is the maximum value to ensure that precision will not be lost if it is converted back to float?

For example, for an integer, we know that its binary representation is 101. now, let's shift the two digits right to 1.01, and remove the hidden valid digit 1 in the high position, the binary value of 5 stored in double is as follows:
The code is as follows:
0/* symbol bit */10000000001/* Index bit */0100000000000000000000000000000000000000000000000000

The binary representation of 5 is stored in the tail part without any loss. in this case, the transfer from double to long will not cause loss of precision.

We know that double represents the ending number with 52 bits, and the hidden first 1 is regarded as the total precision of 53 bits .. then we can conclude that if the value of a long integer is smaller:
The code is as follows:
2 ^ 53-1 = 9007199254740991; // keep in mind that we now assume that it is a long

Then, this integer will not be lost in precision when the value of long-> double-> long is converted.

Pluphp is a weak type language. such a feature requires seamless and transparent implicit type conversion. PHP uses zval to store any of them internally...

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.