当前位置:网站首页>Accuracy of BigDecimal Division
Accuracy of BigDecimal Division
2022-07-05 17:34:00 【Full stack programmer webmaster】
Hello everyone , I meet you again , I'm your friend, Quan Jun .
BigDecimal The accuracy of division
In the use of BigDecimal Division time , Encounter a ghost animal problem , The accuracy of this calculation , Result use return 0, Of course, I finally found that my posture was wrong , So record , Avoid repeating the mistakes later
I. Ask questions
In the use of BigDecimal When doing high-precision Division , I encountered a small problem when I didn't pay attention , as follows
@Test
public void testBigDecimal() {
BigDecimal origin = new BigDecimal(541253);
BigDecimal now = new BigDecimal(12389431);
BigDecimal val = origin.divide(now, RoundingMode.HALF_UP);
System.out.println(val);
origin = new BigDecimal(541253);
now = new BigDecimal(12389431.3);
val = origin.divide(now, RoundingMode.HALF_UP);
System.out.println(val);
origin = new BigDecimal(541253.4);
now = new BigDecimal(12389431);
val = origin.divide(now, RoundingMode.HALF_UP);
System.out.println(val);
}
Copy code
What is the output above ?
0
0
0.043686703610520937021487456961257
Copy code
Why are the first two 0 Well , If it's directly 541253 / 12389431
= 0 It's understandable , however BigDecimal Isn't it a high-precision calculation , To be reasonable, there should not be such a problem of division
We know that BigDecimal When triggering , You can specify parameters to keep decimals , If you add this , Will it be different ?
BigDecimal origin = new BigDecimal(541253);
BigDecimal now = new BigDecimal(12389431);
BigDecimal val = origin.divide(now, 5, RoundingMode.HALF_UP);
System.out.println(val);
Copy code
The output is :
0.04369
Copy code
So after the decimal point is specified , No problem , So make a bold guess , Is it some of the above case in , because scale When the value is not specified , The default values are different , Which leads to different accuracy of the final result ?
Simple in-depth source code analysis , The way of execution is origin.divide(now, RoundingMode.HALF_UP);
, So this scale Parameters are aimed origin object , And this object , We can only analyze its structure , Because there is no other place to use
II. Source location
1. Shaping parameter transmission structure
Analyze the following line , Go straight to source
BigDecimal origin = new BigDecimal(541253);
Copy code
The obvious int Pass parameter structure , Go in and have a brief look
// java.math.BigDecimal#BigDecimal(int)
public BigDecimal(int val) {
this.intCompact = val;
this.scale = 0;
this.intVal = null;
}
public BigDecimal(long val) {
this.intCompact = val;
this.intVal = (val == INFLATED) ? INFLATED_BIGINT : null;
this.scale = 0;
}
Copy code
so, Clearly know the default scale by 0, That is to say, when origin Positive number , Division with it , Unrealistic designation scale When parameters are , The final returns are all without decimals , Take the same look , also long The way of transmitting reference , BigInteger It's the same thing
2. Floating point parameter transfer
The next step is floating point scale The default value confirms , This structure is a little more complex than the previous one , Source code is not posted , Too long , I don't quite understand what I did , Directly in a more obscene way , Get into debug Pattern , Step by step
@Test
public void testBigDecimal() {
BigDecimal origin = new BigDecimal(541253.0);
BigDecimal now = new BigDecimal(12389431.1);
BigDecimal tmp = new BigDecimal(0.0);
}
Copy code
according to debug Result , first ,scale by 0; the second scale by 29, Third scale by 0
3. String The ginseng
It's still a bunch of logic , Also use one-step debug Try... In a different way
@Test
public void testBigDecimal() {
BigDecimal origin = new BigDecimal("541253.0");
BigDecimal now = new BigDecimal("12389431.1");
BigDecimal t = new BigDecimal("0.0");
}
Copy code
The top three scale All are 1
4. Summary
- about BigDecimal In Division , It is best to specify its scale Parameters , Or there might be a hole
- about BigDecimla Of scale The principle of initialization , Need to take a closer look BigDecimal How did it happen
II. other
1. A gray Blog: https://liuyueyi.github.io/hexblog
A grey personal blog , Keep a record of all the blogs in your study and work , Welcome to visit
2. Statement
Better to believe than to believe , What has been said , It's all in one family , Because of limited personal ability , There are inevitably omissions and mistakes , If found bug Or better advice , Welcome criticism and correction , Thank you very much
Publisher : Full stack programmer stack length , Reprint please indicate the source :https://javaforall.cn/149837.html Link to the original text :https://javaforall.cn
边栏推荐
- CMake教程Step5(添加系统自检)
- Judge whether a string is a full letter sentence
- Machine learning 02: model evaluation
- C (WinForm) the current thread is not in a single threaded unit, so ActiveX controls cannot be instantiated
- 漫画:有趣的海盗问题 (完整版)
- Redis+caffeine two-level cache enables smooth access speed
- URP下Alpha从Gamma空间到Linner空间转换(二)——多Alpha贴图叠加
- 漫画:如何实现大整数相乘?(上) 修订版
- Rider 设置选中单词侧边高亮,去除警告建议高亮
- 求解为啥all(())是True, 而any(())是FALSE?
猜你喜欢
Knowledge points of MySQL (6)
CMake教程Step1(基本起点)
MySQL queries the latest qualified data rows
7 pratiques devops pour améliorer la performance des applications
Knowledge points of MySQL (7)
Oracle recovery tools -- Oracle database recovery tool
In depth understanding of redis memory obsolescence strategy
Read the basic grammar of C language in one article
Seven Devops practices to improve application performance
MYSQL group by 有哪些注意事项
随机推荐
Is it safe for China Galaxy Securities to open an account? How long can I buy stocks after opening an account
ICML 2022 | Meta提出鲁棒的多目标贝叶斯优化方法,有效应对输入噪声
CMake教程Step1(基本起点)
Abnormal recovery of virtual machine Oracle -- Xi Fenfei
CMake教程Step4(安装和测试)
Cartoon: how to multiply large integers? (I) revised version
URP下Alpha从Gamma空间到Linner空间转换(二)——多Alpha贴图叠加
Machine learning 01: Introduction
ICML 2022 | Meta提出魯棒的多目標貝葉斯優化方法,有效應對輸入噪聲
How MySQL uses JSON_ Extract() takes JSON value
机器学习01:绪论
C#(Winform) 当前线程不在单线程单元中,因此无法实例化 ActiveX 控件
統計php程序運行時間及設置PHP最長運行時間
Read the history of it development in one breath
Understand the usage of functions and methods in go language
Knowledge points of MySQL (6)
世界上最难的5种编程语言
SQL Server(2)
深入理解Redis内存淘汰策略
MYSQL group by 有哪些注意事项