Those pits that PHP stepped on (5) floating point calculation

Source: Internet
Author: User
Tags php website square root

There's a pit ahead.

PHP uses subtraction and other operators to calculate floating-point numbers, often unexpected results, especially on the financial data aspects of the calculation, to many engineers caused a lot of trouble. For example, today's work has finally reached a case:

$a = 2586;

$b = 2585.98;

Var_dump ($a-$b);

The expected result is: float (0.02)

Actual results:

Float (0.019999999999982)

There's a hole in life, beware

Second, anti-crater Raiders:

1. Convert to Integer plus minus by 100, then divide by 100 to convert back ...

2, use Number_format to convert to string, then use (float) strong turn back ...

3, PHP provides a high-precision calculation of the function library, in fact, to solve the problem of floating point calculation is born.

The main functions are:

Bcadd-adds two high-precision numbers

Bccomp-compares two high-precision numbers, returns-1, 0, 1

bcdiv-divides two high-precision numbers

Bcmod-seeking high precision digital remainder

bcmul-multiply two high-precision numbers

bcpow-High Precision Digital exponentiation

Bcpowmod-to find high-precision digital exponentiation, number theory is very common

bcscale-Configure the default number of decimal places, equivalent to the "scale=" in the Linux BC

bcsqrt-to find the square root of high precision number

bcsub-to subtract two high-precision numbers

The first two rogue methods are not tested, using BCSUB to test the third two-digit subtraction example,

First Look at Bcsub usage (from official website)

String Bcsub (String $left _operand, String $right _operand [, int $scale = int])

Parameters

Left_operand the left operand of the string type.

Right_operand the right operand of the string type.

Scale This optional parameter is used to set the number of decimal digits after the decimal points of the result. You can also set the global default number of decimal digits for all functions by using Bcscale ().

The return value returns the subtraction after which the result is a string type.

Test code:

Var_dump (Bcsub ($a, $b, 2));

Results

0.02

For other functions, please refer to the official PHP website.

Third, why there is a pit:

PHP bug? No, this is a problem that all languages basically encounter, so basically most languages provide a class library or library of accurate computing.

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.

The key point here is that the decimal is the binary representation, how do decimals convert to binary?

The algorithm is multiplied by 2 until there are no decimals. Here, for example, 0.9 is represented as a binary number

0.9*2=1.8 Take integer Part 1

0.8 (fractional part of 1.8) *2=1.6 take integer portion 1

0.6*2=1.2 Take integer Part 1

0.2*2=0.4 take integer part 0

0.4*2=0.8 take integer part 0

0.8*2=1.6 Take integer Part 1

0.6*2=1.2 take integer part 0

.........

0.9 binary is represented as (from top down): 1100100100100 ...

Note: The above calculation process loops, that is, * * can never eliminate the fractional part, so that the algorithm will be indefinitely. It is clear that the binary representation of decimals is sometimes impossible to be precise. In fact, the reason is very simple, decimal system can be accurately expressed in 1/3? The same binary system cannot accurately represent 1/10. This explains why floating-point subtraction has a "lost" precision loss problem.

In other words: We see decimal decimals, which are stored in a computer that is not an exact number and cannot be accurate. So there are unexpected results after the digital subtraction.

Four, anti-crater tips

For these reasons, never believe that the floating-point number is accurate to the last, and never compare two floating-point numbers for equality. If you do need a higher precision, you should use any mathematical or GMP function with any precision.

Those pits that PHP stepped on (5) floating point calculation

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.