This is the 25th day of my participation in the August Challenge

1. Frequently asked Questions

I do not know whether we often encounter data accuracy problems in the development process, such as the following:

<? The PHP $a = 0.57; echo intval(floatval($a) * 100);Copy the code

The expected output is 57, but it is 56. The results may surprise you.

2. Follow up questions

So there’s a question, right? Why is the actual output different than expected? Is this a bug in PHP?

First we need to know the representation of floating point numbers (IEEE 754) :

Floating-point numbers, such as 64-bit lengths (double precision), are represented by 1 sign bit (E), 11 exponent bits (Q), and 52 mantissa bits (M) (total 64 bits)

  • Sign bit: the highest bit represents the positive and negative data, 0 represents a positive number, 1 represents a negative number;

  • Exponent bit: indicates the power base 2 of the data. The exponent is represented by offset code.

  • Mantissa: indicates the significant digit after the decimal point.

3. Pull the wool out of the cocoon

The crux of the matter, it seems, is the binary representation of decimals.

Let’s see how decimals are expressed in binary:

So you multiply the decimal by 2, and you take the whole number, and then you multiply the rest of the decimal by 2, and then you multiply the rest of the decimal by 2, and you go all the way to the decimal, but if you keep multiplying a 0.57 like this, you can’t get a 0. The decimal of significant bits is infinite in binary.

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

0010001111010111000010100011110101110000101000111101
Copy the code

If there were only 52 digits

0.57 = 0.56999999999999995Copy the code

After 100, intval is 56. .

So, the point of this problem is that your seemingly infinite decimals are infinite in the binary representation of a computer

4. Experience and suggestions

For high-precision data operations, the following functions are recommended:

  • Bcadd – Adds two high-precision numbers

  • Bccomp – Compares two high precision numbers, returning -1, 0, 1

  • Bcdiv – Divides two high-precision digits

  • Bcmod – High precision digital remainder

  • Bcmul – Multiply two high-precision numbers

  • Bcpow – High precision digital power

  • Bcpowmod – high precision digital power module, number theory is very common

  • Bcscale – Configures the default number of decimal places, equivalent to “scale=” in Linux BC

  • BCSQRT – High precision square root of numbers

  • Bcsub – Subtracts two high precision numbers

– END –

Author: The road to architecture Improvement, ten years of research and development road, Dachang architect, CSDN blog expert, focus on architecture technology precipitation learning and sharing, career and cognitive upgrade, adhere to share practical articles, looking forward to growing with you. Attention and private message I reply “01”, send you a programmer growth advanced gift package, welcome to hook up.

Thanks for reading!