CS-Wiki CS-Wiki
Home
知识体系总览
  • 数据结构与算法
  • 计算机网络
  • 操作系统
  • MySQL
  • Redis
  • 设计模式
  • Java 基础
  • Java 集合
  • Java 并发
  • Java 虚拟机
  • Spring
  • Kafka
  • 校招扫盲
  • 项目推荐
  • 唠唠嗑儿
  • 读书笔记
归档
GitHub (opens new window)
Home
知识体系总览
  • 数据结构与算法
  • 计算机网络
  • 操作系统
  • MySQL
  • Redis
  • 设计模式
  • Java 基础
  • Java 集合
  • Java 并发
  • Java 虚拟机
  • Spring
  • Kafka
  • 校招扫盲
  • 项目推荐
  • 唠唠嗑儿
  • 读书笔记
归档
GitHub (opens new window)
  • 小牛肉的操作系统知识体系结构
  • 入门

    • 了解操作系统的那些事儿,从这篇文章开始
    • 安全气囊给我来了个缓存:论缓冲与缓存
    • 虎牙一面:内核缓冲区
    • 浮点数运算坏了吗?
      • CPU 和 CPU Core 有啥区别?多核 CPU?多个 CPU?
      • 五年经验的前端社招被问:CPU 和 GPU 到底有啥区别?
    • 进程管理

    • 内存管理

    • 网络通信

    • 20-操作系统
    • 入门
    小牛肉
    2022-07-11
    目录

    浮点数运算坏了吗?

    看下面这段代码

    0.1 + 0.2 == 0.3  ->  Output: false
    0.1 + 0.2         ->  Output: 0.30000000000000004
    

    0.1 + 0.2 != 0.3,什么情况?

    先上答案:0.1 + 0.2 != 0.3 这个问题的症结在于:在现今的计算机中,数字的最终存储(表示)格式是二进制,是整数乘以 2 的幂。所以一切分母不是 2 的幂的有理数(例如 0.1,即 1/10)都是无法被计算机精确表示的。

    下面来详细分析:

    # 十进制小数与二进制的转换

    整数十进制转二进制大伙都知道(除 2 取余法),我们来看看小数是怎么转二进制的

    小数部分的转换不同于整数部分,它采用的是乘 2 取整法:将十进制中的小数部分乘以 2,得到一个数,将这个数的整数位作为二进制的一位,然后继续取其小数部分乘以 2 作为下一位,直到不存在小数为止

    举个例子:3.14(十进制)

    整数部分:

    • 3(十进制)-> 0011(二进制)

    小数部分:

    • 0.14 x 2 = 0.28(将十进制 3 中的小数部分 0.14 乘以 2,得到一个数 0.28,将这个数的整数位 0 作为二进制的一位,然后继续取其小数部分乘以 2 作为下一位,直到不存在小数为止),此时小数部分的二进制表示是 0xxx xxxx
    • 0.28 x 2 = 0.56(将十进制 0.28 中的小数部分 0.28 乘以 2,得到一个数 0.56,将这个数的整数位 0 作为二进制的一位,然后继续取其小数部分乘以 2 作为下一位,直到不存在小数为止),此时小数部分的二进制表示是 00xx xxxx
    • 0.56 x 2 = 1.12(将十进制 0.56 中的小数部分 0.56 乘以 2,得到一个数 1.12,将这个数的整数位 1 作为二进制的一位,然后继续取其小数部分乘以 2 作为下一位,直到不存在小数为止),此时小数部分的二进制表示是 001x xxxx
    • .......

    问题就出现了~

    如果小数部分一直没法变成 0,那么小数部分的二进制表示将是无穷无尽的。

    由于计算机的资源是有限的,所以没办法用二进制精确的表示这些小数部分一直没法变成 0 的数,只能用【近似值】来表示(现在基本采用的都是 IEEE 754 标准,https://en.wikipedia.org/wiki/IEEE_754#Basic_and_interchange_formats),这不可避免地就会造成精度缺失

    # Working with Floats in Programming

    在平常写代码的时候,这个精度问题意味着我们需要使用舍入函数将浮点数四舍五入到我们需要的小数位,然后再显示它们。

    还需要用【允许一定差距(allow some amount of tolerance)的比较】来替换浮点数之间的相等比较 ==,这意味着:

    不要使用:if (x == y) { ... }

    而是使用:if (abs(x - y) < myToleranceValue) { ... }.

    🎁 公众号

    各位小伙伴大家好呀,叫我小牛肉就行,目前在读东南大学硕士,上方扫码关注公众号「飞天小牛肉」,与你分享我的成长历程与技术感悟~

    帮助小牛肉改善此页面 (opens new window)
    Last Updated: 2023/02/16, 11:27:10
    虎牙一面:内核缓冲区
    CPU 和 CPU Core 有啥区别?多核 CPU?多个 CPU?

    ← 虎牙一面:内核缓冲区 CPU 和 CPU Core 有啥区别?多核 CPU?多个 CPU?→

    最近更新
    01
    关于编程满天星
    02
    让我来告诉你 Java 程序员是怎么一步一步从入行到被裁的
    06-08
    03
    Vision Pro,未来已来
    06-06
    更多文章>
    Theme by Vdoing | Copyright © 2019-2023 飞天小牛肉 | 皖ICP备2022008966号
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式