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 相关文章推荐
在一个form用一个SUBMIT(或button)分别提交到两个处理表单页面的代码
Feb 15 Javascript
javascript 混合的构造函数和原型方式,动态原型方式
Dec 07 Javascript
Extjs 几个方法的讨论
Jan 28 Javascript
加速IE的Javascript document输出的方法
Dec 02 Javascript
jQuery中replaceAll()方法用法实例
Jan 16 Javascript
JavaScript实现复制内容到粘贴板代码
Mar 31 Javascript
前端框架学习总结之Angular、React与Vue的比较详解
Mar 14 Javascript
JS匹配日期和时间的正则表达式示例
May 12 Javascript
lhgcalendar时间插件限制只能选择三个月的实现方法
Jul 03 Javascript
小程序实现投票进度条
Nov 20 Javascript
js实现消灭星星(web简易版)
Mar 24 Javascript
JavaScript直接调用函数与call调用的区别实例分析
May 22 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
十天学会php之第三天
2006/10/09 PHP
Yii中实现处理前后台登录的新方法
2015/12/28 PHP
thinkPHP5.0框架开发规范简介
2017/03/25 PHP
MSN消息提示类
2006/09/05 Javascript
传智播客学习之JavaScript基础篇
2009/11/13 Javascript
写了10年的Javascript也未必全了解的连续赋值运算
2011/03/25 Javascript
Jquery带搜索框的下拉菜单
2013/05/06 Javascript
文本框中禁止非数字字符输入比如手机号码、邮编
2013/08/19 Javascript
通过JS来动态的修改url,实现对url的增删查改
2014/09/01 Javascript
jQuery动画出现连续触发、滞后反复执行的解决方法
2015/01/28 Javascript
基于jquery css3实现点击动画弹出表单源码特效
2015/08/31 Javascript
js实现兼容IE、Firefox的图片缩放代码
2015/12/08 Javascript
在Mac OS上安装使用Node.js的项目自动化构建工具Gulp
2016/06/18 Javascript
微信小程序 摇一摇抽奖简单实例实现代码
2017/01/09 Javascript
jquery dataTable 获取某行数据
2017/05/05 jQuery
使用vue制作探探滑动堆叠组件的实例代码
2018/03/07 Javascript
Webpack中publicPath路径问题详解
2018/05/03 Javascript
jQuery实现滑动星星评分效果(每日分享)
2019/11/13 jQuery
在vue中使用echarts(折线图的demo,markline用法)
2020/07/20 Javascript
[02:47]DOTA2英雄基础教程 野性怒吼兽王
2013/12/05 DOTA
[03:37]2014DOTA2国际邀请赛 主赛事第一日胜者组TOPPLAY
2014/07/19 DOTA
Python中用pycurl监控http响应时间脚本分享
2015/02/02 Python
浅谈python为什么不需要三目运算符和switch
2016/06/17 Python
基于python list对象中嵌套元组使用sort时的排序方法
2018/04/18 Python
python中csv文件的若干读写方法小结
2018/07/04 Python
Python中fnmatch模块的使用详情
2018/11/30 Python
Python实现最大子序和的方法示例
2019/07/05 Python
10个很棒的 CSS3 开发工具 推荐
2011/05/16 HTML / CSS
豪华床上用品 :Jennifer Adams
2019/09/15 全球购物
最新创业融资计划书
2014/01/19 职场文书
电子专业毕业生自我鉴定
2014/01/22 职场文书
执行总经理岗位职责
2014/02/03 职场文书
学习决心书范文
2014/03/11 职场文书
中班下学期个人总结
2015/02/12 职场文书
2016党校培训心得体会
2016/01/07 职场文书
护士自荐信范文(2016推荐篇)
2016/01/28 职场文书