当前位置:网站首页>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);
}
}
边栏推荐
猜你喜欢
随机推荐
Telnet,SSH1,SSH2,Telnet/SSL,Rlogin,Serial,TAPI,RAW
mongodb查看表是否导入成功
Add PDF Title floating window
ROS learning (XIX) robot slam function package cartographer
JS Es5 can also create constants?
Image watermarking, scaling and conversion of an input stream
LeetCode. Sword finger offer 62 The last remaining number in the circle
According to the analysis of the Internet industry in 2022, how to choose a suitable position?
ROS learning (23) action communication mechanism
ROS学习(22)TF变换
NPM install compilation times "cannot read properties of null (reading 'pickalgorithm')“
Yiwen takes you into [memory leak]
C language [23] classic interview questions [Part 2]
Make DIY welding smoke extractor with lighting
AcWing 361. 观光奶牛 题解(spfa求正环)
Set up [redis in centos7.x]
百度飞将BMN时序动作定位框架 | 数据准备与训练指南 (下)
Let's see how to realize BP neural network in Matlab toolbox
HDU 4661 message passing (wood DP & amp; Combinatorics)
mysqlbackup 还原特定的表