有这样一道智力题:三人住旅馆,老板娘说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