当前位置:网站首页>Correct use of BigDecimal
Correct use of BigDecimal
2022-07-07 01:55:00 【Dily_ Su】
List of articles
One 、 background
BigDecimal Usually it is mainly used to calculate money , It provides many construction methods by itself , However, the improper use of these construction methods will cause the loss of accuracy , Thus causing accidents .
Two 、 Accident cases
1、 problem
The cashier calculated the commodity price and reported an error , The order cannot be paid
2、 Problem recurrence
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);
}

3、 Source code analysis
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 ).
4、 Cause analysis
stay java in BigDecimal Expand the decimal number when processing data 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 .
3、 ... and 、 summary
When the design reaches the accuracy calculation , We try to use String Type to convert , And it's about BigDecimal The calculation of , Use its corresponding method to calculate .
Four 、 Tool class
Here's a package BigDecimal Tool class
public class BigDecimalUtils {
/** * double Add * * @param v1 Addition number * @param v2 Addition number * @return and */
public static BigDecimal doubleAdd(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.add(b2);
}
/** * float Add * * @param v1 Addition number * @param v2 Addition number * @return and */
public static BigDecimal floatAdd(float v1, float v2) {
BigDecimal b1 = new BigDecimal(Float.toString(v1));
BigDecimal b2 = new BigDecimal(Float.toString(v2));
return b1.add(b2);
}
/** * double reduce * * @param v1 minuend * @param v2 Subtract * @return Bad */
public static BigDecimal doubleSub(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.subtract(b2);
}
/** * float reduce * * @param v1 minuend * @param v2 Subtract * @return Bad */
public static BigDecimal floatSub(float v1, float v2) {
BigDecimal b1 = new BigDecimal(Float.toString(v1));
BigDecimal b2 = new BigDecimal(Float.toString(v2));
return b1.subtract(b2);
}
/** * double ride * * @param v1 Factor * @param v2 Factor * @return product */
public static BigDecimal doubleMul(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.multiply(b2);
}
/** * float ride * * @param v1 Factor * @param v2 Factor * @return product */
public static BigDecimal floatMul(float v1, float v2) {
BigDecimal b1 = new BigDecimal(Float.toString(v1));
BigDecimal b2 = new BigDecimal(Float.toString(v2));
return b1.multiply(b2);
}
/** * double except * * @param v1 Divisor * @param v2 Divisor * @return merchant */
public static BigDecimal doubleDiv(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
// Keep two decimal places ROUND_HALF_UP = rounding
return b1.divide(b2, 2, RoundingMode.HALF_UP);
}
/** * float except * * @param v1 Divisor * @param v2 Divisor * @return merchant */
public static BigDecimal floatDiv(float v1, float v2) {
BigDecimal b1 = new BigDecimal(Float.toString(v1));
BigDecimal b2 = new BigDecimal(Float.toString(v2));
// Keep two decimal places ROUND_HALF_UP = rounding
return b1.divide(b2, 2, RoundingMode.HALF_UP);
}
/** * double<br> * Compare v1 v2 size * * @param v1 * @param v2 * @return v1>v2 return 1 v1=v2 return 0 v1<v2 return -1 */
public static int doubleCompareTo(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.compareTo(b2);
}
/** * float<br> * Compare v1 v2 size * * @param v1 * @param v2 * @return v1>v2 return 1 v1=v2 return 0 v1<v2 return -1 */
public static int floatCompareTo(float v1, float v2) {
BigDecimal b1 = new BigDecimal(Float.toString(v1));
BigDecimal b2 = new BigDecimal(Float.toString(v2));
return b1.compareTo(b2);
}
}
边栏推荐
- Start from the bottom structure to learn the customization and testing of fpga---- FIFO IP
- AcWing 1142. 繁忙的都市 题解(最小生成树)
- Gin 入门实战
- Right mouse button customization
- How can I code for 8 hours without getting tired.
- curl 命令
- ROS learning (21) robot slam function package -- installation and testing of orbslam
- Yiwen takes you into [memory leak]
- JS ES5也可以創建常量?
- 长按按钮执行函数
猜你喜欢

C语言关于链表的代码看不懂?一篇文章让你拿捏二级指针并深入理解函数参数列表中传参的多种形式
![Yiwen takes you into [memory leak]](/img/a8/bd1a57ef3bde8910eff2a5f68296df.png)
Yiwen takes you into [memory leak]

爬虫实战(六):爬笔趣阁小说

@Before, @after, @around, @afterreturning execution sequence

Blue Bridge Cup 2022 13th provincial competition real topic - block painting

Modify the system time of Px4 flight control

ROS learning (23) action communication mechanism

BigDecimal 的正确使用方式
![[unique] what is the [chain storage structure]?](/img/cd/be18c65b9d7faccc3c9b18e3b2ce8e.png)
[unique] what is the [chain storage structure]?

ROS学习(25)rviz plugin插件
随机推荐
@Before, @after, @around, @afterreturning execution sequence
ROS learning (21) robot slam function package -- installation and testing of orbslam
How can I code for 8 hours without getting tired.
ROS学习(十九)机器人SLAM功能包——cartographer
AcWing 361. 观光奶牛 题解(spfa求正环)
Make DIY welding smoke extractor with lighting
字符串转成日期对象
Appium automation test foundation uiautomatorviewer positioning tool
String to date object
ROS学习(24)plugin插件
grep查找进程时,忽略grep进程本身
AcWing 904. Wormhole solution (SPFA for negative rings)
Recognition of C language array
454 Baidu Mianjing 1
ZOJ problem set – 2563 long dominoes [e.g. pressure DP]
永久的摇篮
AcWing 346. 走廊泼水节 题解(推公式、最小生成树)
CISP-PTE之命令注入篇
sql中批量删除数据---实体中的集合
JS ES5也可以創建常量?