当前位置:网站首页>Do you dare to use BigDecimal without mastering these pits?
Do you dare to use BigDecimal without mastering these pits?
2022-07-23 17:30:00 【InfoQ】
background
BigDecimal summary
BigDecimal Of 4 Pit
First of all : Floating point type pit
@Test
public void test0(){
float a = 1;
float b = 0.9f;
System.out.println(a - b);
}
Copy code @Test
public void test1(){
BigDecimal a = new BigDecimal(0.01);
BigDecimal b = BigDecimal.valueOf(0.01);
System.out.println("a = " + a);
System.out.println("b = " + b);
}
Copy code a = 0.01000000000000000020816681711721685132943093776702880859375
b = 0.01
Copy code public static BigDecimal valueOf(double val) {
// Reminder: a zero double returns '0.0', so we cannot fastpath
// to use the constant ZERO. This might be important enough to
// justify a factory approach, a cache, or a few private
// constants, later.
return new BigDecimal(Double.toString(val));
}
Copy code BigDecimal(int) Create an object with the integer value specified by the parameter .
BigDecimal(double) Create an object with the double value specified by the parameter .
BigDecimal(long) Create an object with the long integer value specified by the parameter .
BigDecimal(String) Create an object with a string value specified by the parameter .
Copy code second : Pit of floating-point precision
@Test
public void test2(){
BigDecimal a = new BigDecimal("0.01");
BigDecimal b = new BigDecimal("0.010");
System.out.println(a.equals(b));
System.out.println(a.compareTo(b));
}
Copy code @Override
public boolean equals(Object x) {
if (!(x instanceof BigDecimal))
return false;
BigDecimal xDec = (BigDecimal) x;
if (x == this)
return true;
if (scale != xDec.scale)
return false;
long s = this.intCompact;
long xs = xDec.intCompact;
if (s != INFLATED) {
if (xs == INFLATED)
xs = compactValFor(xDec.intVal);
return xs == s;
} else if (xs != INFLATED)
return xs == compactValFor(this.intVal);
return this.inflated().equals(xDec.inflated());
}
Copy code Third : Set the accuracy of the pit
@Test
public void test3(){
BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("3.0");
a.divide(b);
}
Copy code java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
at java.math.BigDecimal.divide(BigDecimal.java:1690)
...
Copy code ArithmeticException @Test
public void test3(){
BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("3.0");
BigDecimal c = a.divide(b, 2,RoundingMode.HALF_UP);
System.out.println(c);
}
Copy code - RoundingMode.UP: Rounding away from zero . Always increase the number before discarding the non-zero part ( Always add... To the number in front of the non-zero discard part 1). Be careful , This rounding mode never reduces the size of the calculated value .
- RoundingMode.DOWN: Rounding mode close to zero . Never increase the number before discarding a part ( Never give up the number in front of the part plus 1, That is, cut it short ). Be careful , This rounding mode never increases the size of the calculated value .
- RoundingMode.CEILING: A rounding pattern close to positive infinity . If BigDecimal Being positive , Then the behavior and ROUNDUP identical ; If a negative , Then the behavior and ROUNDDOWN identical . Be careful , This rounding mode never reduces the calculated value .
- RoundingMode.FLOOR: A rounding pattern close to negative infinity . If BigDecimal Being positive , Then the behavior and ROUNDDOWN identical ; If a negative , Then the behavior and ROUNDUP identical . Be careful , This rounding mode never increases the calculated value .
- RoundingMode.HALF_UP: towards “ The closest ” Round off the numbers , If the distance from two adjacent numbers is equal , It is the rounding mode of rounding up . If you give up part >= 0.5, Then the behavior and ROUND_UP identical ; Otherwise, the behavior and ROUND_DOWN identical . Be careful , This is the rounding pattern we learned in primary school ( rounding ).
- RoundingMode.HALF_DOWN: towards “ The closest ” Round off the numbers , If the distance from two adjacent numbers is equal , Is the rounding mode of rounding up . If you give up part > 0.5, Then the behavior and ROUND_UP identical ; Otherwise, the behavior and ROUND_DOWN identical ( Round to the nearest ).
- RoundingMode.HALF_EVEN: towards “ The closest ” Round off the numbers , If the distance from two adjacent numbers is equal , Round to the adjacent even number . If the number to the left of the discarded part is odd , Then the behavior and ROUNDHALFUP identical ; If it's an even number , Then the behavior and ROUNDHALF_DOWN identical . Be careful , When repeating a series of calculations , This rounding mode minimizes the cumulative error . This rounding mode is also known as “ Banker's Rounding ”, Mainly used in the United States . Round to the nearest , In two fifths . If the previous one is odd , Then enter , Otherwise, give up . The following example is to keep the decimal point 1 position , So the result of this rounding .1.15 ==> 1.2 ,1.25 ==> 1.2
- RoundingMode.UNNECESSARY: Assert that the requested operation has exact results , So no rounding is required . If this rounding mode is specified for the operation to get accurate results , Throw out ArithmeticException.
Fourth : Three kinds of string output pits
@Test
public void test4(){
BigDecimal a = BigDecimal.valueOf(35634535255456719.22345634534124578902);
System.out.println(a.toString());
}
Copy code 3.563453525545672E+16
Copy code - toPlainString(): Don't use any scientific counting ;
- toString(): Use scientific counting when necessary ;
- toEngineeringString() : Use engineering counting when necessary . It's similar to scientific counting , It's just that the powers of the exponents are 3 Multiple , This is convenient for engineering applications , Because in many unit conversions it's 10^3;
NumberFormat currency = NumberFormat.getCurrencyInstance(); // Create currency formatting references
NumberFormat percent = NumberFormat.getPercentInstance(); // Create percentage formatting references
percent.setMaximumFractionDigits(3); // Percentages have the most decimal points 3 position
BigDecimal loanAmount = new BigDecimal("15000.48"); // amount of money
BigDecimal interestRate = new BigDecimal("0.008"); // The interest rate
BigDecimal interest = loanAmount.multiply(interestRate); // Multiply
System.out.println(" amount of money :\t" + currency.format(loanAmount));
System.out.println(" The interest rate :\t" + percent.format(interestRate));
System.out.println(" interest :\t" + currency.format(interest));
Copy code amount of money : ¥15,000.48
The interest rate : 0.8%
interest : ¥120.00
Copy code Summary
边栏推荐
- 动态库*.dll文件的Debug/Release版本是否可以混用(交叉用)?
- keras——accuracy_ Score formula
- Shrimp noodles: what do you know about the JVM memory layout?
- Could not load dynamic library ‘cudnn64_8.dll‘; dlerror: cudnn64_8.dll not found
- Detailed explanation of SQL error reporting and blind annotation
- 小程序商城如何精细化运营?
- USB通信协议深入理解
- KV260单板PS控制设置IIC开关芯片
- Kubernetes kubelet hard core knowledge architecture
- Sorting - introduction, code ideas, usage suggestions, code implementation -1
猜你喜欢
随机推荐
Pymoo learning (3): use multi-objective optimization to find the set of optimal solutions
Major upgrade of openim - group chat reading diffusion model release group management function upgrade
VSCode PIO创建工程失败分析和解决办法
OpenIM重大优化-消息按需加载 一致性缓存 uniapp发布
一加OnePlus 10T的一系列规格在产品发布前被披露
Pymoo learning (4): multi criteria decision making
Leetcode question brushing record
Food safety chocolate is also true or false? How much do you know about it
gom及gee架设黑屏的原因以及个别装备地图不显示怎么办?
【Js】检查Date对象是否为Invalid Date
keras——accuracy_score公式
单细胞论文记录(part19)--A comprehensive comparison on cell-type composition inference for ST data
职场3道坎:年薪30万、50万、100万
[introduction series of redis] data types and related commands of redis
What about the reason why GOM and GEE set up a black screen and the fact that individual equipment maps are not displayed?
食品安全|选购益生菌类产品,你必须知道的八件事
Keil errors and solutions (1): fcarm - output name not specified, please check 'options for target - Utilities‘
Typescript 清空数组
大规模团队中的敏捷测试实践
OpenCV求两个区域的交集









