第一次学Java的时候,我们一般从基本的数据类型开始学习,但是在基本的数据类型中,我觉得double型很难理解。 另外,在今后的学习和工作中,double型数据这个漏洞也很多。 例如以下程序
publicstaticvoidmain (字符串[ ]数组) {
system.out.println(2.0-1.1;
}
很多人以为上述程序要打印0.9,但实际上为什么要打印0.8999999999999999呢?
首先,介绍十进制小数是如何转换为二进制数的。 作为例子列举3.75
首先,取出3.75的小数部分0.75,将其乘以转换为的进制数。 这里也就是说,是2。 乘以2得到1.5,1.5的整数部分取二进制小数部分的第一位,再乘以1.5的小数部分0.5,乘以2得到1.0,1.0的整数部分1为小数部分的第二位。 这样,最终得到值0或无限循环。 将3.75转换为二进制数后为11.11
但是,由于Java中知道double型数据占8字节,所以对于无限循环的二进制小数只能取其近似值,例如1.1。
以下自己编写了将double型的数转换为二进制的程序
publicstaticvoidmain (字符串[ ]数组) {
doubletobinary(3.75000000;
杜比(173.8125;
doubletobinary(1.10;
}
//*
* 10负幂无法准确表示为长度有限的二进制数
* @param d
*/
公共卫生组织
获取双精度类型的整数部分
intintpart=(int ) d;
字符串tempstr=d ';
获取double类型数字符串形式的小数部分
stringdecimalpartstr=tempstr.substring (tempstr .索引为('.' ) );
bigdecimal decimal=新bigdecimal (decimalpartstr;
//得到小数点以后的位数
int precision=decimal.precision (;
//最终小数部分的二进制字符串
stringdecimalpartbinary=decimalparttobinary (双重分区,精度);
system.out.println (整合部件) '.'增量部件';
}
//*
* *将小数部分转换为二进制字符串
* * @ param数位零件小数部
* @param precision原始数的小数点后位数
* * @返回
*/
公共卫生部门(双重医疗部门,内部精度) {
转换为//整数
长医学零件长=(长) (math.pow(10,精度) *医学零件);
字符串时间戳=' ';
int i=0;
wile (精准0 I 64 ) {
ecimalpartlong=decimalpartlong * 2;
temp=(整数) ) 10,精度);
获取除去第//1位后的数,转换为字符串
stringstr=(长) ) decimalpartlong%math.pow(10,precision ) ';
if (str.charat (-1 )=='0' str.length )!=1) {
//去掉数字最后的0
decimalpartlong=long.parse long (str.substring (0,str.length(-1 ) );
} else {
ecimalpartlong=long.parse long (str;
}
if (微分零件长==0) {
布莱克;
}
I;
precision=(微分零件长' ' ).length );
}
返回时间表;
}
上的程序的main方法输出的值为
11.11
10101101.1101
1.000110011001100110011001100110011001100110011001100110011001100110011001100110011001100111001110001111000111111000011111111000001
在上面的步骤中,我们很容易看到测试数据1.10在小数部分无限循环,1.10无法准确地表示为一个double,因此在Java中表示为与其最接近的double值。 由于在Java中以近似值存储了double无法正确表现的数量,因此需要正确计算的地方可能会发生错误或产生意想不到的结果。 例如,业务中经常遇到的货币计算。 那么,如何解决这个问题呢?
1 .使用执行准确小数运算的BigDecimalAPI。 但是,这里有一个说明,不是用bigdecimal(doubleval ),而是用bigdecimal )构建方法是最好的)。 因为BigDecimal(doubleval )构造方法使用该参数val的准确值返回bigdecimal。 例如,newbigdecimal ) 1.1 )返回一个值,表示1.10000000000081784197001252389000000
2 .使用int和long等整数型进行计算。 如果将2.0元转换为200点进行计算,则system.out.println((200-110 ) '点) ) )将打印正确的结果90点。
总之,在需要准确计算的地方,不要使用浮点和双精度数据。