专栏首页未闻Code一日一技:为什么浮点数在计算机中可能不准确?

一日一技:为什么浮点数在计算机中可能不准确?

大多数人在小学奥数或者初中数学里面都学过如何把一个整数转换为二进制:

反复除以2,从后往前取余数。

例如:把数字247转换为二进制数:

247 / 2 = 123 余 1123 /2 = 61 余 161 / 2 = 30 余 130 / 2 = 15 余 015 / 2 = 7 余 17 / 2 = 3 余 13 / 2 = 1 余 11 < 2,结束

把余数倒过来,就得到了: 11110111这就是247对应的二进制数。

那么一个浮点数如何转换为二进制数呢?

浮点数分为整数部分和小数部分,整数部分按整数转二进制的方法处理,小数部分按如下方法处理:

反复乘以2,取小数点左边的部分。如果乘积大于1,减1。简称:乘基取整。每次乘完以后把小数点左边的数从左到右按顺序排列。直到积为0时结束。

分别转换好以后,重新拼接起来。

例如:把0.2转换为二进制。

  1. 0.2 x 2 = 0.4,小数点左边部分为0
  2. 0.4 x 2 = 0.8,小数点左边部分为0
  3. 0.8 x 2 = 1.6,小数点左边部分为1
  4. 移除小数点左边的部分,重新变为0.6
  5. 0.6 x 2 = 1.2,小数点左边为1
  6. 移除小数点左边的部分,重新变为0.2
  7. 0.2 x 2 = 0.4,小数点左边部分为0
  8. 0.4 x 2 = 0.8,小数点左边部分为0
  9. 0.8 x 2 = 1.6,小数点左边部分为1
  10. 移除小数点左边的部分,重新变为0.6
  11. 0.6 x 2 = 1.2,小数点左边为1
  12. 移除小数点左边的部分,重新变为0.2
  13. ...

看到规律了吗?这个步骤可以无限循环下去,所以0.2对应的二进制数为: 0.00110011001100110011...

12.2转换为二进制: 1100.00110011001100110

但是计数机是不能处理无限循环数据的,所以现在的家用计算机,会把浮点数对应的二进制数保留53位,53位后面的数据直接截断。

所以,0.2对应的二进制数,在计算机中就会成为:

0.0011001100110011001100110011001100110011001100110011001100110011

此时的这个64位的二进制数,显然和原来的无限循环二进制数不一样。

所以说,浮点数转换为二进制以后,可能会不准确。

但也有例外,例如0.125:

  1. 0.125 x 2 = 0.25 小数点左边为0
  2. 0.25 x 2 = 0.5 小数点左边为0
  3. 0.5 x 2 = 1.0 小数点左边为1
  4. 1.0移除1以后成为0,0乘以任何数都为0,结束

所以0.125对应的二进制数为0.001,这是一个准确的二进制数,不是近似值。

同理,0.375对应的二进制数为0.011,也是准确的值。

本文分享自微信公众号 - 未闻Code(itskingname)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-04-02

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 前端-现代 js 框架存在的根本原因

    我曾见过很多很多人盲目地使用(前端)框架,如 React,Angular 或 Vue 等等。这些框架提供了许多有意思的东西,然而通常人们(自以为)使用框架是因为...

    grain先森
  • 最全的JS数组去重

    数组去重,一般都是在面试的时候才会碰到,一般是要求手写数组去重方法的代码。如果是被提问到,数组去重的方法有哪些?你能答出其中的10种,面试官很有可能对你刮目相看...

    grain先森
  • 前端代码规范

    (1)用两个空格来代替制表符(tab) -- 这是唯一能保证在所有环境下获得一致展现的方法。

    grain先森
  • 选机器学习,还是深度学习?看完不纠结

    大哥你好,我是来学「人工智能」的。但是,啥是「深度学习」?啥是「机器学习」?「深度学习」和「机器学习」有啥关系?我究竟该学「深度学习」还是「机器学习」?

    商业新知
  • 前端-vue 和微信小程序的区别、比较

    写了vue项目和小程序,发现二者有许多相同之处,在此想总结一下二者的共同点和区别。

    grain先森
  • async/await 和 promise

    所以我写这个的文章,主要还是交流学习,如果您已经清楚了eventloop/async/await/promise 这些东西呢,可以 break 啦。

    grain先森
  • JS 执行上下文

    运行JavaScript代码时,当代码执行进入一个环境时,就会为该环境创建一个执行上下文,它会在你运行代码前做一些准备工作,如确定作用域,创建局部变量对象等。

    grain先森
  • 创建型模式:单例模式

    Ensure a class has only one instance, and provide a global point of access to it...

    LieBrother
  • JS 小技巧

    可以用*1来转化为数字(实际上是调用.valueOf方法) 然后使用Number.isNaN来判断是否为NaN,或者使用 a !== a 来判断是否为NaN,因...

    grain先森
  • 前端- CSS 变量让你轻松制作响应式网页

    原文:https://medium.freecodecamp.org/how-to-make-responsiveness-super-simple-with-...

    grain先森

扫码关注云+社区

领取腾讯云代金券