首页 > 编程语言 > 详细

一块钱哪里去了?--java浮点型背后的故事

时间:2019-09-01 16:36:23      阅读:48      评论:0      收藏:0      [点我收藏+]

有这样一道智力题:三人住旅馆,老板娘说30元她们付钱后进去了,老板娘想起今天是特价25元,就叫伙计拿5元还给三位顾客,可伙计藏了2元,给了她们3元,这样她们每人得1元,就是说每人付了9元,那3*9=27,再加伙计藏的2元,等于29元,那还有1元哪里去啦?

很多人疑惑蛮久,这剩下的1块钱到底去了哪里?我们用角色分析一下:

老板:实得到25元

伙计:实得 2元

客户:付出3*9=27成本

27=25+2 成本和收益是平衡的。上面主要是混淆了逻辑。

但在java开发中,你的钱也许一不小心就会丢失哦,请看题!

技术分享图片

 

public class TestFloatDouble {
public static void main(String[] args) {
System.out.println(0.05f+0.01f);
System.out.println(1.0f-0.42f);
System.out.println(4.015d*100);
System.out.println(123.3d/100);
}
}

猜对话,有大奖!哈哈

0.060000002
0.58000004
401.49999999999994
1.2329999999999999

我们发现在使用浮点数类型float或者double进行运算时,数据有可能会失真。是上面原因呢?

我们知道,计算机并不能识别除了二进制数据以外的任何数据。无论我们使用何种编程语言,在何种编译环境下工作,都要先 把源程序翻译成二进制的机器码后才能被计算机识别。以上面提到的情况为例,我们来验证一下

public class TestFloatDouble {
public static void main(String[] args) {
System.out.println(Float.toHexString(0.05f));
System.out.println(Float.toHexString(0.01f));
System.out.println(Float.toHexString(1.0f));
System.out.println(Float.toHexString(0.42f));

System.out.println(Double.toHexString(4.015d));
System.out.println(Double.toHexString(123.3d));

System.out.println(0.05f+0.01f);
System.out.println(1.0f-0.42f);
System.out.println(4.015d*100);
System.out.println(123.3d/100);
}
}

其结果为:

0x1.47ae14p-7
0x1.0p0
0x1.ae147ap-2
0x1.00f5c28f5c28fp2
0x1.ed33333333333p6
0.060000002
0.58000004
401.49999999999994
1.2329999999999999

其中:ox表示十六进制

p表示指数,其基数是2

应该是不难理解的。

技术分享图片

 

总之, 在需要精确答案的地方,要避免使用float 和double;对于货币计算,要使用int、long 或BigDecimal。

参考资料:

【1】https://blog.csdn.net/aya19880214/article/details/45891581

一块钱哪里去了?--java浮点型背后的故事

原文:https://www.cnblogs.com/davidwang456/p/11442177.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!