js为什么不能正确处理小数运算?


Posted in Javascript onDecember 29, 2015
var sum = 0;
for(var i = 0; i < 10; i++) {
 sum += 0.1;
}

console.log(sum);

上面的程序会输出1吗?

你有必要知道的 25 个 JavaScript 面试题 一文中,第 8 个题浅显的说了下 js 为什么不能正确处理小数运算的问题。今天重拾旧题,更深层次的剖析下这个问题。

但要先说明的是,不能正确处理小数的运算并不是 JavaScript 语言本身的设计错误,其它高级编程语言,如C,Java等,也是不能正确处理小数运算的:

#include <stdio.h>

void main(){
  float sum;
  int i;
  
  sum = 0;
  
  for(i = 0; i < 100; i++) {
    sum += 0.1;
  }
  
  printf('%f\n', sum); //10.000002
}

数在计算机内部的表示

我们都知道,用高级编程语言编写的程序需要经过解释、编译等操作转变成 CPU(Central Processing Unit) 可以识别的机器语言才能运行,而对 CPU 来说,它不识别数的十进制、八进制和十六进制等,我们在程序中声明的这些进制数都会被转成二进制数进行运算。

为什么不是转换成三进制数进行运算呢?

计算机内部是由很多的 IC (Integrated Circuit: 集成电路) 这种电子部件构成的,它的长相大概是这样子:

js为什么不能正确处理小数运算?

IC 有很多种形状,在其两侧或内部并排排列着很多引脚(图示只画出了一侧)。IC 的所有引脚,只有直流电压 0V 或 5V 两个状态,即一个 IC 引脚只能表示两个状态。IC 的这个特性就决定了计算机内部的数据只能用二进制数处理。

由于1 位(一个引脚)只能表示两个状态,所以二进制的计算方式就变成了 0、1、10、11、100….这种形式:

js为什么不能正确处理小数运算?

所以,在数的运算中,所有操作数都会被转成二进制数参与运算,如39,会被转换成二进制 00100111

小数的二进制表示

如前文所说,程序中的数据都会被转换成二进制数,小数参与运算时,也会被转成二进制,如十进制的11.1875 会被转换成1101.0010。

小数点后 4 位用二进制数表示的数值范围是 0.0000~0.1111,因此,这只能表示 0.5、0.25、0.125、0.0625 这四个十进制数以及小数点后面的位权组合(相加)而成的小数:

js为什么不能正确处理小数运算?

从上表可以看出,十进制数 0 的下一位是 0.0625,所以,0~0.0625 之间的小数,就无法用小数点后 4 位数的二进制数表示;如果增加二进制数小数点后面的位数,与其相对应的十进制数的个数也会增加,但无论增加多少位,都无法得到 0.1 这个结果。实际上,0.1 转换成二进制是 0.00110011001100110011…… 注意 0011 是无限重复的:

console.log(0.2+0.1);

//操作数的二进制表示
0.1 => 0.0001 1001 1001 1001…(无限循环)
0.2 => 0.0011 0011 0011 0011…(无限循环)

js 的 Number 类型并没有像 C / Java 等分整型、单精度、双精度等,而是统一表现为双精度浮点型。按照 IEEE 的规定,单精度浮点数用 32 位表示全体小数,而双精度浮点数用 64 位表示全体小数,而浮点数由符号、尾数、指数和基数组成,所以并不是所有的位数都用来表示小数,符号、指数等也要占据位数,基数不占据位数:

js为什么不能正确处理小数运算?

双精度浮点数的小数部分最多支持 52 位,所以两者相加之后得到这么一串 0.0100110011001100110011001100110011001100…因浮点数小数位的限制而截断的二进制数字,这时候,再把它转换为十进制,就成了 0.30000000000000004。

总结

js 不能正确处理小数运算,包括其它高级编程语言一样,这不是语言本身的设计错误,而是计算机内部本身就不能正确处理小数的运算,对小数的运算往往会得到意想不到的结果,因为并不是所有的十进制小数能被二进制表示。

以上就是本文的全部内容,希望对大家的学习有所帮助。

Javascript 相关文章推荐
表单提交时自动复制内容到剪贴板的js代码
Mar 16 Javascript
跟我学习javascript的prototype使用注意事项
Nov 17 Javascript
Jquery中map函数的用法
Jun 03 Javascript
AngularJS实现路由实例
Feb 12 Javascript
jQuery插件Echarts实现的双轴图效果示例【附demo源码下载】
Mar 04 Javascript
详解angular ui-grid之过滤器设置
Jun 07 Javascript
详解如何使用Node.js编写命令工具——以vue-cli为例
Jun 29 Javascript
浅谈Vue.set实际上是什么
Oct 17 Javascript
JavaScript中this函数使用实例解析
Feb 21 Javascript
VUE页面中通过双击实现复制表格中内容的示例代码
Jun 11 Javascript
javascript前端实现多视频上传
Dec 13 Javascript
JavaScript实现打字游戏
Feb 19 Javascript
javascript从作用域链谈闭包
Jul 29 #Javascript
你有必要知道的25个JavaScript面试题
Dec 29 #Javascript
JavaScript仿支付宝密码输入框
Dec 29 #Javascript
js实现商城星星评分的效果
Dec 29 #Javascript
原生js配合cookie制作保存路径的拖拽
Dec 29 #Javascript
一种新的javascript对象创建方式Object.create()
Dec 28 #Javascript
JavaScrip常见的一些算法总结
Dec 28 #Javascript
You might like
判断Keep-Alive模式的HTTP请求的结束的实现代码
2011/08/06 PHP
PHP图片库imagemagick安装方法
2014/09/23 PHP
php构造函数的继承方法
2015/02/09 PHP
php中instanceof 与 is_a()区别分析
2015/03/03 PHP
jQuery判断元素是否是隐藏的代码
2011/04/24 Javascript
js实现addClass,removeClass,hasClass的函数代码
2011/07/13 Javascript
异步动态加载js与css文件的js代码
2013/09/15 Javascript
JS模拟按钮点击功能的方法
2015/12/22 Javascript
JS组件中bootstrap multiselect两大组件较量
2016/01/26 Javascript
用js实现放大镜的效果的简单实例
2016/05/23 Javascript
jQuery EasyUI右键菜单实现关闭标签/选项卡
2016/10/10 Javascript
js中创建对象的几种方式
2017/02/05 Javascript
JS实现的简单拖拽功能示例
2017/03/13 Javascript
JS实现按钮颜色切换效果
2020/09/05 Javascript
React操作真实DOM实现动态吸底部的示例
2017/10/23 Javascript
Javascript摸拟自由落体与上抛运动原理与实现方法详解
2020/04/08 Javascript
vue使用axios实现excel文件下载的功能
2020/07/16 Javascript
R vs. Python 数据分析中谁与争锋?
2017/10/18 Python
Python使用django框架实现多人在线匿名聊天的小程序
2017/11/29 Python
Python中的单继承与多继承实例分析
2018/05/10 Python
Python根据已知邻接矩阵绘制无向图操作示例
2018/06/23 Python
Pycharm中出现ImportError:DLL load failed:找不到指定模块的解决方法
2019/09/17 Python
Pandas时间序列基础详解(转换,索引,切片)
2020/02/26 Python
Ubuntu18.04安装 PyCharm并使用 Anaconda 管理的Python环境
2020/04/08 Python
PyCharm上安装Package的实现(以pandas为例)
2020/09/18 Python
Canvas制作的下雨动画的示例
2018/03/06 HTML / CSS
瑜伽服装品牌:露露柠檬(lululemon athletica)
2017/06/04 全球购物
GWebs公司笔试题
2012/05/04 面试题
体育专业个人的求职信范文
2013/09/21 职场文书
党的群众路线教育实践活动通讯稿
2014/09/10 职场文书
土地转让协议书
2014/09/27 职场文书
优秀学生干部主要事迹材料
2015/11/04 职场文书
2016廉洁从业学习心得体会
2016/01/19 职场文书
详解RedisTemplate下Redis分布式锁引发的系列问题
2021/04/27 Redis
WINDOWS 64位 下安装配置mysql8.0.25最详细的教程
2022/03/22 MySQL
海康机器人重磅发布全新算法开发平台VM4.2
2022/04/21 数码科技