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

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

老板:实得到25元

伙计:实得 2元

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

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

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

  1. 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);
    }
    }

猜对话,有大奖!哈哈

  1. 0.060000002
    0.58000004
    401.49999999999994
    1.2329999999999999

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

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

  1. 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));
  2.  
  3. System.out.println(Double.toHexString(4.015d));
    System.out.println(Double.toHexString(123.3d));
  4.  
  5. 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);
    }
    }

其结果为:

  1. 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浮点型背后的故事的更多相关文章

  1. java浮点型比较大小

    ======1   java浮点型比较大小 Float.parseFloat(String)和Float.valueOf(String).floatValue()的区别 Float.parseFloa ...

  2. 更好的 java 重试框架 sisyphus 背后的故事

    sisyphus 综合了 spring-retry 和 gauva-retrying 的优势,使用起来也非常灵活. 今天,让我们一起看一下西西弗斯背后的故事. 情景导入 简单的需求 产品经理:实现一个 ...

  3. 7个连环问揭开java多线程背后的弯弯绕

    摘要:很多java入门新人一想到java多线程, 就会觉得很晕很绕,什么可见不可见的,也不了解为什么sync怎么就锁住了代码. 本文分享自华为云社区<java多线程背后的弯弯绕绕到底是什么? 7 ...

  4. Mac OS X 背后的故事

    Mac OS X 背后的故事 作者: 王越  来源: <程序员>  发布时间: 2013-01-22 10:55  阅读: 25840 次  推荐: 49   原文链接   [收藏]   ...

  5. DbUtility v3 背后的故事

    DbUtility v3 背后的故事 时间 DbUtility v3构思了差不多大半年,真正开发到第一个版本发布到NuGet却只花了50天.中途大量时间在完善 Jumony 3,只有三周来开发DbUt ...

  6. 腾讯技术分享:微信小程序音视频技术背后的故事

    1.引言 微信小程序自2017年1月9日正式对外公布以来,越来越受到关注和重视,小程序上的各种技术体验也越来越丰富.而音视频作为高速移动网络时代下增长最快的应用形式之一,在微信小程序中也当然不能错过. ...

  7. 背后的故事之 - 快乐的Lambda表达式(一)

    快乐的Lambda表达式(二) 自从Lambda随.NET Framework3.5出现在.NET开发者眼前以来,它已经给我们带来了太多的欣喜.它优雅,对开发者更友好,能提高开发效率,天啊!它还有可能 ...

  8. 背后的故事之 - 快乐的Lambda表达式(二)

    快乐的Lambda表达式 上一篇 背后的故事之 - 快乐的Lambda表达式(一)我们由浅入深的分析了一下Lambda表达式.知道了它和委托以及普通方法的区别,并且通过测试对比他们之间的性能,然后我们 ...

  9. ASP.NET Web API自身对CORS的支持: EnableCorsAttribute特性背后的故事

    从编程的角度来讲,ASP.NET Web API针对CORS的实现仅仅涉及到HttpConfiguration的扩展方法EnableCors和EnableCorsAttribute特性.但是整个COR ...

随机推荐

  1. MySQL常用工具、日志及读写分离

    MySQL常用工具.日志及读写分离 1.MySQL中常用工具 1.1 mysql 1.1.1连接选项 1.1.2 执行选项 1.2 mysqladmin 1.3 mysqlbinlog 1.4 mys ...

  2. java - 如何使一个类不能被继承

    使用final关键字: 使用私有构造器: public final class InitTest{ private InitTest(){} }

  3. PIVOT内置函数实现行转列

    PIVOT用于将列值旋转为列名(即行转列),PIVOT的一般语法是:PIVOT(聚合函数(列) FOR 列 in (…) )AS P 完整语法: table_source PIVOT( 聚合函数(va ...

  4. 灵活使用Maven Profile

    项目中一直应用Maven的profile特性解决不同环境的部署问题.最近在尝试解决本地调试环境的时候碰到一些问题,顺便仔细研究了一下.因为项目仍然在用普通SpringMVC架构,没有切换到Spring ...

  5. Xcode 常用

    常用快捷键: 1. 运行程序 command + R 2. Clean command + shift + K 3. 模拟器上没 Home 键? command + shift + H 4. h 文件 ...

  6. 多线程编程(Linux C)

    多线程编程可以说每个程序员的基本功,同时也是开发中的难点之一,本文以Linux C为例,讲述了线程的创建及常用的几种线程同步的方式,最后对多线程编程进行了总结与思考并给出代码示例. 一.创建线程 多线 ...

  7. FB的新专利竟要监看使用者的脸

    大家应该会很好奇Facebook又在搞什么新花招,这个专利的名称是"Techniques for emotion detection and content delivery",其 ...

  8. 使用用树莓派打造远程WEB服务器

    简介:系统配置Raspberry Pi 3B + Raspbian + MySQL5.7 + Tomcat 9 + Nginx + 公网IP. 工具:Win32DiskImager .FileZill ...

  9. 9-2、大型项目的接口自动化实践记录----递归判断两个json串是否相等

    1.已知json串构成的情况下判断 先构造一下场景,假设已经把各个数据都移除掉不对比的字段 图1 预期.实际结果,复杂接口返回多层嵌套json时,同下 图2 预期.实际结果值为:{child_json ...

  10. 映射&集合

    哈希函数 通过哈希表可以实现 O(1) 复杂度的查找. 哈希函数构造方法:设计好的哈希函数的两个基本原则,计算简单+分布均匀 1. 直接定址法 用key自身的某个线性函数来定址,f(key) = a* ...