[读书笔记][Effective Java]不要在精确计算中使用float和double类型
2006-08-11 10:50
375 查看
在精确计算,尤其是有关金钱的商业运算中,不能使用float和double类型。
看如下的例子:
商店里某种糖果的价格是0.1元,0.2元,0.3元, …… 依此类推,一直到1.00元。现在你手中有1元钱。你想买一些糖果,假设你从1角的糖果开始依次买,一种价格的买一颗。计算一下一共可以买多少颗糖果,最后会剩下多少零钱。
第一个程序:
package com.mytest;
public class Test {
private static final double FUNDS = 1.00;
private static final double TEN_CENTS = .1;
public static void main( String[] args ) {
int itemsBought = 0;
double myfund = FUNDS;
for (double price = TEN_CENTS; price < myfund; price+= TEN_CENTS) {
itemsBought++;
myfund-= price;
}
System.out.println("itemsBought: " + itemsBought);
System.out.println("myfund left: " + myfund);
}
}
在这里,使用double类型,进行计算,但是却得到如下结果:
itemsBought: 3
myfund left: 0.3999999999999999
这并不是正确的结果。在涉及金钱的运算中,应该使用BigDecimal。
正确的程序如下:
package com.mytest;
import java.math.BigDecimal;
public class Test {
private static final BigDecimal FUNDS = new BigDecimal("1.00");
private static final BigDecimal TEN_CENTS = new BigDecimal(".10");
public static void main( String[] args ) {
int itemsBought = 0;
BigDecimal myfund = FUNDS;
for (BigDecimal price = TEN_CENTS; price.compareTo(myfund) <= 0; price = price.add(TEN_CENTS)) {
itemsBought++;
myfund = myfund.subtract(price);
}
System.out.println("itemsBought: " + itemsBought);
System.out.println("change: " + myfund);
}
}
打印结果:
itemsBought: 4
change: 0.00
这才是正确的答案。
In summary, don't use float or double for any calculations that require an exact answer. User BigDecimal if you want the system to keep track of the decimal point and you don't mind the inconveneice of not using a primitive type. Using BigDecimal has the added advantage that it gives you full controll over rounding, letting you select from eight rounding modes whenever an operation that entails rounding is performed. This comes in handy if you're performing business calculations with legally mandated rounding behaviour. If performance is of the essence, if you don't mind keeping track of the decimal point yourself, and if the quantities aren't too big, use int or long. If the quantitiest don't exceed nine decimal digits, you can use int; if they don't exceed eighteen digits, you can use long. If the quantities exceed eighting digits, you must use BigDecimal.
看如下的例子:
商店里某种糖果的价格是0.1元,0.2元,0.3元, …… 依此类推,一直到1.00元。现在你手中有1元钱。你想买一些糖果,假设你从1角的糖果开始依次买,一种价格的买一颗。计算一下一共可以买多少颗糖果,最后会剩下多少零钱。
第一个程序:
package com.mytest;
public class Test {
private static final double FUNDS = 1.00;
private static final double TEN_CENTS = .1;
public static void main( String[] args ) {
int itemsBought = 0;
double myfund = FUNDS;
for (double price = TEN_CENTS; price < myfund; price+= TEN_CENTS) {
itemsBought++;
myfund-= price;
}
System.out.println("itemsBought: " + itemsBought);
System.out.println("myfund left: " + myfund);
}
}
在这里,使用double类型,进行计算,但是却得到如下结果:
itemsBought: 3
myfund left: 0.3999999999999999
这并不是正确的结果。在涉及金钱的运算中,应该使用BigDecimal。
正确的程序如下:
package com.mytest;
import java.math.BigDecimal;
public class Test {
private static final BigDecimal FUNDS = new BigDecimal("1.00");
private static final BigDecimal TEN_CENTS = new BigDecimal(".10");
public static void main( String[] args ) {
int itemsBought = 0;
BigDecimal myfund = FUNDS;
for (BigDecimal price = TEN_CENTS; price.compareTo(myfund) <= 0; price = price.add(TEN_CENTS)) {
itemsBought++;
myfund = myfund.subtract(price);
}
System.out.println("itemsBought: " + itemsBought);
System.out.println("change: " + myfund);
}
}
打印结果:
itemsBought: 4
change: 0.00
这才是正确的答案。
In summary, don't use float or double for any calculations that require an exact answer. User BigDecimal if you want the system to keep track of the decimal point and you don't mind the inconveneice of not using a primitive type. Using BigDecimal has the added advantage that it gives you full controll over rounding, letting you select from eight rounding modes whenever an operation that entails rounding is performed. This comes in handy if you're performing business calculations with legally mandated rounding behaviour. If performance is of the essence, if you don't mind keeping track of the decimal point yourself, and if the quantities aren't too big, use int or long. If the quantitiest don't exceed nine decimal digits, you can use int; if they don't exceed eighteen digits, you can use long. If the quantities exceed eighting digits, you must use BigDecimal.
相关文章推荐
- 不要在精确计算中使用float和double类型
- 不要在精确计算中使用float和double类型
- 精确计算时,不要使用float或double
- 在对于精确计算的要求下请不要使用float和double
- 不要用float和double来进行精确的小数计算
- Java中需要精确计算的,不要用float, double, 请用BigDecimal
- 《effective java》48—如果需要精确的答案,请避免使用float和double
- 天天记录 - Java 精确计算避免使用float和double
- Effective Java(2nd Edition) Item 48 如果需要精确结果,请避免使用float与double(译文)
- 做精确计算时应避免使用float和double
- c语言中计算int,float,double,char四种数据类型所能表示的数据范围
- double类型的精确计算工具
- Java:Effective Java 学习笔记(第48条:如果需要精确的答案,请避免使用float和double)
- Effective Java读书笔记--如果想要知道精确的答案,就要避免使用double和float
- double*等指针类型所占字节数 float* long* int* short* 要求用sizeof 运算符计算C++中char*
- Java浮点数float和double精确计算的精度误差问题总结
- 如果要求精确的答案,请避免使用float和double
- 需要精确答案,避免使用float和double
- 使用 C++ bitset 操纵浮点数类型(float、double)