当前位置:网站首页>Improper use of BigDecimal caused P0 accident!
Improper use of BigDecimal caused P0 accident!
2022-07-20 21:54:00 【hello-java-maker】
Recommended today
Reduce try-catch , This is grace !
An addictive new generation of development artifacts , Say goodbye to Controller、Service、Dao Other methods
SpringBoot Realize face recognition function
believe me , Use Stream Can really make the code more elegant !
The most detailed thread pool in the whole network ThreadPoolExecutor Reading !
Batch splitting with multithreading List Import database , Efficiency bars !
Source of the article :https://c1n.cn/MSqAy
Catalog
background
accident
analysis
summary
Tool sharing
background
When we use the amount to calculate or display the amount, we often use BigDecimal, It is also a very recommended type when it comes to the amount .
BigDecimal It also provides many constructor methods , Improper use of these constructor methods may cause unnecessary trouble or even loss of money , Thus causing accident asset loss .
accident
Next, let's look at an accident at the cashier .
| Problem description
The cashier reported an error in calculating the amount of goods , The order cannot be paid .
| Accident level
P0
| Accident process
as follows :
13:44, Get the alarm , Order payment failed , Payment availability reduced to 60%
13:50, Quickly roll back online code , Back to normal
14:20,review Code , Problems found in pre release verification
14:58, Modify the problem code to go online , Online recovery
| The cause of the problem
BigDecimal Lost precision in amount calculation .
Cause analysis
First, let's use a piece of code to reproduce the root cause of the problem , As shown below :
public static void main(String[] args) {
BigDecimal bigDecimal=new BigDecimal(88);
System.out.println(bigDecimal);
bigDecimal=new BigDecimal("8.8");
System.out.println(bigDecimal);
bigDecimal=new BigDecimal(8.8);
System.out.println(bigDecimal);
}
The results are as follows :
Found by test , When using double perhaps float These floating-point data types , Will lose precision ,String、int Will not be , Why is that ?
Let's open the constructor method to see the source code :
public static long doubleToLongBits(double value) {
long result = doubleToRawLongBits(value);
// Check for NaN based on values of bit fields, maximum
// exponent and nonzero significand.
if ( ((result & DoubleConsts.EXP_BIT_MASK) ==
DoubleConsts.EXP_BIT_MASK) &&
(result & DoubleConsts.SIGNIF_BIT_MASK) != 0L)
result = 0x7ff8000000000000L;
return result;
}
The problem is doubleToRawLongBits In this way , stay jdk in double class (float And int Corresponding ) Provided in double And long transformation ,doubleToRawLongBits Will be double Convert to long, This method is the original method ( The bottom is not java Realization , yes c++ Realized ).
double The reason why something goes wrong , It's because the decimal point to binary lost precision .
BigDecimal Expand decimal number in processing N Times make it count on integers , And keep the corresponding precision information .
①float and double type , It is mainly designed for scientific calculation and engineering calculation , The reason for performing binary floating-point operations , It is designed to provide accurate and fast approximate sum calculation over a wide range of numerical values .
② It doesn't provide completely accurate results , So it should not be used for precise results .
③ When the floating-point number reaches a certain large number , Will automatically use scientific counting , Such a representation is only approximate to the real number but not equal to the real number .
④ When decimals are converted to binary, there will be infinite cycles or the length of the floating-point mantissa will be exceeded .
summary
therefore , In the process of precision calculation , We try to use String Type to convert .
Last , Recommend a planet of my knowledge , Join now , front 100 name , It only needs 25 element that will do , Very favorable .
边栏推荐
- 2019电赛复测测试题
- 基于BS架构的微博系统
- 2022河南萌新联赛第(二)场:河南理工大学 G - 无限
- Microblogging system based on BS architecture
- Using redis + Lua script to realize distributed flow restriction
- 【面试必刷101】贪心算法、模拟、字符串
- FFmpeg 音视频截取
- Vs2017 can't be used after the 30 day trial. There is a problem with the login interface card owner
- 关于list循环这件事(foreach的五种写法)
- About the list loop (five ways of writing foreach)
猜你喜欢
Quickly install VMware tool for stm32mp157 development board
[record of question brushing] 15 Sum of three numbers
Dest0g3 520 orientation -web easyphp
Quels sont les écouteurs Bluetooth pour cadeaux? Top 10 Bluetooth Headset 2022
stm32移植RT-Thread Nano实现finsh全步骤
記錄一下十三届藍橋杯嵌入式省賽題目
Record the title of the 13th Landbridge cup embedded provincial competition
Microblogging system based on BS architecture
MySQL MVCC你了解吗
马斯克称已将大脑上传到云端【系统或已开源】
随机推荐
森马做LP的背后,“温州系”正跑步进入创投圈
渗透测试靶机实战-SQL注入getshell
Summary on sorting and de duplication of sets
Musk said that he had uploaded his brain to the cloud [the system may have been open source]
2022 Henan Mengxin League game (2): Henan University of technology C - Zhanlong
PMP每日一练 | 考试不迷路-7.19
Simple examples of pointer arrays and array pointers
马斯克称已将大脑上传到云端【系统或已开源】
PCBA方案设计——蓝牙智能营养秤方案
金仓数据库 KingbaseES SQL 语言参考手册 (3.10. 数据库对象引用方式)
The LAAS protocol of defi 2.0 is the key to revitalizing the development of defi track
SQL optimization related
关于list循环这件事(foreach的五种写法)
北京邮电大学|RIS辅助室内多机器人通信系统的联合深度强化学习
Vs2017 can't be used after the 30 day trial. There is a problem with the login interface card owner
2022 National latest fire-fighting facility operator (primary fire-fighting facility operator) simulation questions and answers
English sentence pattern reference exclusive Edition - subject clause - predicative clause
mysql8.0新特性-自增变量的持久化
Jincang database kingbasees SQL language reference manual (3.3. type conversion table, 3.4. constants)
About the list loop (five ways of writing foreach)