PHP floating-point number FAQ for PHP floating point _php Tutorial

Source: Internet
Author: User
Tags mathematical functions

A common problem with PHP floating-point numbers, PHP floating-point FAQ


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

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 actual value of the values itself is the Zvalue_value consortium:

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;

Today's topic, we only focus on two of the members, Lval and Dval, we have to realize that long lval is the same as the compiler, the length of the OS is variable, it may be 32bits or 64bits, and double dval (double precision) by the IEEE 754 provisions , is fixed-length, must be 64bits.

Keep this in mind, creating a "non-platform agnostic" code for PHP. Our next discussion, except for the special specification, assumes that long is 64bits

IEEE 754 Floating-point counting method, I do not reference here, we are interested to see for themselves, the key point is that the mantissa of the double with 52 bit to save, count the hidden 1 bits, total is 53bits.

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

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 at the end of the article)

Now we are back to the point, PHP before executing a script, the first need to read into the script, parsing the script, the process is also included, the script in the literal zval, for example, for the following script:

<?php$a = 9223372036854775807; 64-bit signed maximum value $b = 9223372036854775808; Maximum value +1var_dump ($a); Var_dump ($b);

Output:

Int (9223372036854775807) float (9.22337203685E+18)

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

We have to be careful about values that are greater than the maximum integer value, because it can have a loss of precision:

<?php$a = 9223372036854775807; $b = 9223372036854775808; Var_dump ($a = = = ($b-1));

The output is false.

Now the beginning of the discussion, said before, the whole number of PHP, may be 32-bit, or 64-bit, then decided that some of the 64-bit can run normal code, may be due to the invisible type conversion, the loss of precision, resulting in the code does not run properly on the 32-bit system.

Therefore, we must be wary of this threshold value, fortunately, in PHP has defined the threshold value:

<?php echo Php_int_max;?>

Of course, for the sake of insurance, we should use a string to hold large integers, and use a library of mathematical functions such as bcmath for calculations.

In addition, there is a key configuration that will confuse us, this configuration is php.precision, this configuration determines the PHP output a float value when the output of the number of significant bits.

Finally, we look back at the question raised above, that is, a long integer, the maximum value is to ensure that after going to float and then back to long will not occur loss of precision?

For example, for integers, we know that its binary representation is, 101, now, let's move the two bits to the right, turn 1.01, take the implied significant bit 1 of the high, and we get the binary value that stores 5 in a double:

0/* sign bit */10000000001/* digit */0100000000000000000000000000000000000000000000000000
5 of the binary representation, the slightest loss of preservation in the tail part, in this case, from a double transfer back to long, there will be no loss of precision.

We know that double uses 52 bits to denote the mantissa, counting the implied first 1, which is a total of 53 bits of precision. Then it can be concluded that if a long integer, the value is less than:

2^53-1 = = 9007199254740991; Remember, we now assume that it is a long of 64bits
So, this integer, in the event of a numeric conversion of long->double->long, the loss of precision will not occur.

Another point about floating-point numbers is the answer to the following FAQ:

<?php $f = 0.58; Var_dump (Intval ($f * 100)); Why output 57?>

Why is the output 57? PHP bug?

I believe that a lot of students have had this kind of doubt, because the light asks me the similar question person to be many, not to mention bugs.php.net often people ask ...

To understand this, first we need to know the representation of floating-point numbers (IEEE 754):

Floating-point numbers, in the case of a 64-bit length (double), take the 1-bit sign bit (E), 11 exponent (Q), and 52-bit mantissa (M) (altogether 64 bits).

Sign bit: The highest bit represents the positive or negative of the data, 0 is a positive number, and 1 indicates a negative number.

Digits: Indicates that the data is a power of 2, and the exponent is represented by an offset code

Mantissa: A valid number that represents the decimal point of the data.

Here is the key point is that the decimal in the binary representation, about how to use binary decimal notation, you can Baidu, I do not repeat here, we key to understand, 0.58 for the binary representation, is an infinitely long value (the following number omitted the implied 1):

The binary representation of 0.58 is basically (52 bits) is: 0010100011110101110000101000111101011100001010001111
The binary representation of 0.57 is basically (52 bits) is: 0010001111010111000010100011110101110000101000111101

and the binary of both, if only through the 52-bit calculation, respectively:

0.58-0.57999999999999996
0.57-0.56999999999999995

As for the 0.58 * 100 of the specific floating-point multiplication, we do not consider so thin, interesting to see (floating point), we are vague in mental arithmetic to see ... 0.58 * 100 = 57.999999999

Then you intval, Nature is 57 ....

Visible, the key point of this problem is: "You seem to have a poor decimal, in the computer binary representation is infinite"

So, do not think this is a PHP bug, this is the case .....

Articles you may be interested in:

    • An introduction to integer types and floating-point numbers for PHP data types
    • Use of PHP's sprintf function to control floating-point format
    • Calculation of floating-point numbers in PHP and the solution of inaccurate rounding
    • PHP determines whether two floating-point numbers are equal
    • PHP floating point Accuracy problem summary
    • You should know PHP floating point knowledge
    • Two float (floating point) Comparison example analysis in PHP
    • Simple talk about the exact operation of PHP floating point numbers

http://www.bkjia.com/PHPjc/1108612.html www.bkjia.com true http://www.bkjia.com/PHPjc/1108612.html techarticle PHP floating point number of a common problem, PHP floating point FAQ php is a weak type of language, such a feature, it is necessary to have a seamless transparent implicit type conversion, PHP internal use zval to protect ...

  • 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.