摘要
Java语言中支持两类非整数类型,float和double(以及包装类Float和Double)。还有一个特殊的类,任意精度小数BigDecimal。大多数编程情况都很少用到浮点数等的运算,但是在实际应用中,这些非整数运算总是出现错误的计算结果。文章将讨论非整数类型的基本原理,如何使用非整数得到正确的结果,以及BigDecimal的推荐使用。
存储原理
计算机中以底数为2的小数来表示浮点数。
(2 -1)。下一位对应(2 -2),以此类推。
对于64位双精度double类型,1位表示数字符号,11位表示指数,其余52位表示小数部分。
| s | exponent | mantissa |
float | 1 | 8 | 23 |
double | 1 | 11 | 52 |
对于数字1.25,float表示值为0 0111 1111 010 0000 0000 0000 0000 0000。其中0表示正数,0111 1111(127)为指数。0.01其值加1的1.01为小数。计算公式为v=(-1)^s*(1*2^1+0*2^0+1*
2
-1)*2^(E-128),所以float类型数据计算公式为
v=(-1)^s*M*2^(E-128)。M表示小数位计算方法,如1.25计算方法。
双精度double计算公式为
v=(-1)^s*M*2^(E-1024),
计算误差
float数据311.29,其真实值是311.2900085449219。浮点数的计算机存储方式注定其不能精确的表示所有数据,因此,float和double型数据在计算过程中的误差是在所难免的。
比较错误
1,运算过程中,当比较其值是否大于0时,由于误差的存在,会出现错误的比较结果。
2,对于特殊情况,无穷大NaN,正负零的比较需特别注意。比如0是不等于-0的。
BigDecimal
BigDecimal,换位因子表示小数点左移的位数。用BigDecimal表示的值为unscaledValue*10 -scale 。
其中一个构造函数以双精度浮点数作为输入,另一个以整数和换算因子作为输入,还有一个以小数的 String 表示作为输入。小心使用 BigDecimal(double)BigDecimal就存在误差。请使用基于整数或 StringBigDecimalBigDecimalBigDecimal时需谨慎,避免用于大量数学计算。
总结
BigDecimal。
2,如果数据计算需要进行四色五入到整数,值加0.5的办法处理。
3,对精度要求不高的环境下,比如测量值,允许存在误差且float和double导致的误差在其范围内。float和double数据原型是比较好的选择。
















