当前位置:网站首页>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);
}
}
边栏推荐
- ROS学习(26)动态参数配置
- 【唯一】的“万字配图“ | 讲透【链式存储结构】是什么?
- The use of video in the wiper component causes full screen dislocation
- How did partydao turn a tweet into a $200million product Dao in one year
- Set up [redis in centos7.x]
- AcWing 1142. 繁忙的都市 题解(最小生成树)
- 我如何编码8个小时而不会感到疲倦。
- 刨析《C语言》【进阶】付费知识【二】
- dvajs的基础介绍及使用
- AcWing 1140. 最短网络 (最小生成树)
猜你喜欢

Gin 入门实战

盒子拉伸拉扯(左右模式)

刨析《C语言》【进阶】付费知识【二】

@Before, @after, @around, @afterreturning execution sequence
![[advanced C language] 8 written questions of pointer](/img/d4/c9bb2c8c9fd8f54a36e463e3eb2fe0.png)
[advanced C language] 8 written questions of pointer

Appium foundation - appium inspector positioning tool (I)

Instructions for using the domain analysis tool bloodhound

ROS学习(25)rviz plugin插件

Mongodb checks whether the table is imported successfully

Analyze "C language" [advanced] paid knowledge [End]
随机推荐
Telnet,SSH1,SSH2,Telnet/SSL,Rlogin,Serial,TAPI,RAW
Comparison of picture beds of free white whoring
golang 基础 —— 数据类型
Yiwen takes you into [memory leak]
猫猫回收站
shell脚本快速统计项目代码行数
各种语言,软件,系统的国内镜像,收藏这一个仓库就够了: Thanks-Mirror
ZOJ Problem Set – 2563 Long Dominoes 【如压力dp】
增加 pdf 标题浮窗
Ros Learning (23) Action Communication Mechanism
Drag to change order
AcWing 361. 观光奶牛 题解(spfa求正环)
centos8 用yum 安装MySQL 8.0.x
AcWing 346. 走廊泼水节 题解(推公式、最小生成树)
The cradle of eternity
Long press the button to execute the function
Ds-5/rvds4.0 variable initialization error
Right mouse button customization
curl 命令
POJ 3177 redundant paths POJ 3352 road construction (dual connection)