问题1:double类型转float类型没有出错,float转double类型出错。
float f = 121.1f;
double d = f;
System.out.println(d);
输出:
121.0999984741211
解决办法1:
float f = 121.1f;
double d ;
BigDecimal bd = new BigDecimal(String.valueOf(f));
d = bd.doubleValue();
System.out.println(d);
输出:
121.1
问题2:
double d = (3.3-2.1)/0.1;
System.out.println(d);
输出:
11.999999999999996
解决办法2:
小数运算时,或可能会产生小数的运算时,都转换成BigDecimal后再进行,得到结果后再转换成相应类型。
如果感觉麻烦,可以写一个基本运算的工具类,
参考博客
说明:
java中整数默认是int,小数默认是double类型。(如要得到float类型,则加f如:12.1f)
int:4字节,long:8字节,float:4字节,double:8字节
float类型的变量只有7位的精度,而double类型的变量有15位的精度。
java在运算时会自动的提升变量的精度来进行运算。(double比float精度更高,所以可以自动的从float转化至double再进行运算。)
BigDecimal介绍:
在《Effective Java》这本书中也提到这个原则,float和double只能用来做科学计算或者是工程计算,在商业计算中我们要用java.math.BigDecimal。BigDecimal一共有4个够造方法,我们不关心用BigInteger来够造的那两个,那么还有两个,它们是:
BigDecimal(double val)
Translates a double into a BigDecimal.
BigDecimal(String val)
Translates the String repre sentation of a BigDecimal into a BigDecimal.
上面的API简要描述相当的明确,而且通常情况下,上面的那一个使用起来要方便一些。我们可能想都不想就用上了,会有什么问题呢?等到出了问题的时候,才发现上面哪个够造方法的详细说明中有这么一段:
Note: the results of this constructor can be somewhat unpredictable. One might assume that new BigDecimal(.1) is exactly equal to .1, but it is actually equal to .1000000000000000055511151231257827021181583404541015625. This is so because .1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the long value that is being passed in to the constructor is not exactly equal to .1, appearances nonwithstanding.
The (String) constructor, on the other hand, is perfectly predictable: new BigDecimal(".1") is exactly equal to .1, as one would expect. Therefore, it is generally recommended that the (String) constructor be used in preference to this one.
原来我们如果需要精确计算,非要用String来够造BigDecimal不可!在《Effective Java》一书中的例子是用String来够造BigDecimal的,但是书上却没有强调这一点,这也许是一个小小的失误吧。
参考文献:http://blog.sina.com.cn/s/blog_68e4d2910100j0x8.html
:http://lava83.blog.163.com/blog/static/317599932010230111342743/
阅读(5572) | 评论(0) | 转发(0) |