当前位置:网站首页>PHP high precision computing
PHP high precision computing
2022-04-23 08:07:00 【Hehe PHPer】
One 、 There is a pit ahead
php When using operators such as addition, subtraction, multiplication and division to calculate floating-point numbers , There are often unexpected results , Especially with regard to the calculation of financial data , Caused a lot of trouble to many engineers . For example, today's work finally arrived in a case :
$a = 2586;
$b = 2585.98;
var_dump($a-$b);
The expected result is :float(0.02)
The actual result :
float(0.019999999999982)
There are pits in life , Beware of everywhere
Two 、 Pit prevention strategy :
1、 By riding 100 The way is transformed into integer addition and subtraction , And then divide by 100 Convert back ……
2、 Use number_format Convert to string , And then use (float) Strong turn back ……
3、php It provides a function library for high-precision calculation , In fact, it is born to solve the problem of floating-point calculation .
The main functions are :
bcadd — Add two high-precision numbers
bccomp — Compare two high-precision numbers , return -1, 0, 1
bcdiv — Divide two high-precision numbers
bcmod — Find high precision digital remainder
bcmul — Multiply two high-precision numbers
bcpow — Find a high-precision digital power
bcpowmod — To find high precision digital power and modulus , It's very common in number theory
bcscale — Configure default decimal places , It's equivalent to Linux bc Medium ”scale=”
bcsqrt — Find the square root of high precision figures
bcsub — Subtract two high-precision numbers
The first two rogue methods are not tested , Use bcsub Test the third example of subtracting two numbers ,
First look at bcsub usage ( From official website )
string bcsub ( string $left_operand , string $right_operand [, int $scale = int ] )
Parameters
left_operand Left operand of string type .
right_operand Right operand of string type .
scale This optional parameter is used to set the number of decimal places after the decimal point in the result . You can also use bcscale() To set the global default decimal places , For all functions .
Return value Returns the result of subtraction as a string .
Test code :
var_dump(bcsub($a,$b,2));
result
0.02
For other functions, please refer to PHP Official website
3、 ... and 、 Why are there pits :
php Of bug? No , This is a problem that almost all languages encounter , Therefore, most languages basically provide class libraries or function libraries for accurate calculation .
To understand why , First of all, we need to know the representation of floating-point numbers (IEEE 754):
Floating point numbers , With 64 The length of bits ( Double precision ) For example , Will be used 1 Bit sign bit (E), 11 Exponential position (Q), 52 Potential mantissa (M) Express ( altogether 64 position ).
Sign bit : The highest bit indicates the positive and negative of the data ,0 It means a positive number ,1 A negative number .
Exponential position : Represent data with 2 The power of the bottom , The exponent is represented by an offset code
mantissa : Represents the significant number after the decimal point of the data .
The key point here is , The representation of decimals in binary , How to convert decimal into binary ?
The algorithm is multiplied by 2 Until there are no decimals . Here's an example ,0.9 Expressed as a binary number
0.9*2=1.8 Take the whole part 1
0.8(1.8 Decimal part of )*2=1.6 Take the whole part 1
0.6*2=1.2 Take the whole part 1
0.2*2=0.4 Take the whole part 0
0.4*2=0.8 Take the whole part 0
0.8*2=1.6 Take the whole part 1
0.6*2=1.2 Take the whole part 0
.........
0.9 Binary representation as ( From the top down ): 1100100100100......
Be careful : The above calculation cycle , in other words *2 It's never possible to eliminate the decimal part , This algorithm will go on indefinitely . Obviously , The binary representation of decimals is sometimes impossible to be exact . In fact, it's very simple , Can decimal system accurately express 1/3 Well ? The binary system also can't express exactly 1/10. This explains why floating-point subtraction occurs " It can't be reduced " The loss of accuracy problem .
let me put it another way : We see decimal decimals , What is stored in the computer is not an exact number , It's impossible to be accurate . So there are unexpected results after digital addition, subtraction, multiplication and division .
Four 、 Pit prevention tips
For the above reasons , So never believe that floating-point results are accurate to the last place , Never compare two floating-point numbers for equality . If higher precision is really needed , You should use any precision mathematical function or gmp function
版权声明
本文为[Hehe PHPer]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204230645420147.html
边栏推荐
猜你喜欢
随机推荐
Chapter V investment real estate
智能名片小程序名片详情页功能实现关键代码
求3个字符串(每串不超过20个字符)中的最大者。
聊聊接口幂等与消费幂等的本质
strcat()、strcpy()、strcmp()、strlen()
NIH降血脂指南《your guide to lowering your Cholesterol with TLC》笔记(持续更新中)
Intranet security attack and defense: a practical guide to penetration testing (6): domain controller security
Talk about the essence of interface idempotent and consumption idempotent
CTF-MISC学习之从开始到放弃
云计算赛项--2020年赛题基础部分[任务3]
MySQL -- the secret of lock -- how to lock data
访问数据库的时候出现错误 Operation not allowed for a result set of type ResultSet.TYPE_FORWARD_ONLY.详解
Analysis of Nacos source code
Link to some good tutorials or notes about network security and record them
Implementation principle of instanceof
Research on system and software security (3)
The displayed amount of ABAP ALV is inconsistent with the exported amount
Internal network security attack and defense: a practical guide to penetration testing (8): Authority maintenance analysis and defense
Intranet penetration series: dns2tcp of Intranet tunnel
Interview learning route









