当前位置:网站首页>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);
}
}
边栏推荐
- json学习初体验–第三者jar包实现bean、List、map创json格式
- ROS学习(22)TF变换
- First experience of JSON learning - the third-party jar package realizes bean, list and map to create JSON format
- Telnet,SSH1,SSH2,Telnet/SSL,Rlogin,Serial,TAPI,RAW
- 爬虫实战(六):爬笔趣阁小说
- ROS学习(十九)机器人SLAM功能包——cartographer
- WCF基金会
- The cradle of eternity
- mongodb查看表是否导入成功
- How to use strings as speed templates- How to use String as Velocity Template?
猜你喜欢
随机推荐
json学习初体验–第三者jar包实现bean、List、map创json格式
百度飞将BMN时序动作定位框架 | 数据准备与训练指南 (下)
POJ 3177 redundant paths POJ 3352 road construction (dual connection)
Errors made in the development of merging the quantity of data in the set according to attributes
ROS学习(十九)机器人SLAM功能包——cartographer
centos8安装mysql报错:The GPG keys listed for the “MySQL 8.0 Community Server“ repository are already ins
AcWing 1142. Busy urban problem solving (minimum spanning tree)
ROS学习(24)plugin插件
字符串转成日期对象
AcWing 346. 走廊泼水节 题解(推公式、最小生成树)
Gin introduction practice
AcWing 346. Solution to the problem of water splashing festival in the corridor (deduction formula, minimum spanning tree)
Golang foundation - data type
Set WordPress pseudo static connection (no pagoda)
Google released a security update to fix 0 days that have been used in chrome
ROS learning (22) TF transformation
Public key \ private SSH avoid password login
AcWing 361. 观光奶牛 题解(spfa求正环)
HDU 4661 message passing (wood DP & amp; Combinatorics)
golang 基础 —— 数据类型