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 相关文章推荐
Javascript 面向对象之重载
May 04 Javascript
Javascript的一种模块模式
Sep 08 Javascript
JavaScript与Div对层定位和移动获得坐标的实现代码
Sep 08 Javascript
js插件设置innerHTML时在IE8下提示“未知运行时错误”解决方法
Apr 25 Javascript
javascript控制层显示或隐藏的方法
Jul 22 Javascript
JavaScript实现身份证验证代码
Feb 17 Javascript
纯JS前端实现分页代码
Jun 21 Javascript
浅谈js中的三种继承方式及其优缺点
Aug 10 Javascript
删除table表格行的实例讲解
Sep 21 Javascript
js正则相关知识点专题
May 10 Javascript
微信小程序API—获取定位的详解
Apr 30 Javascript
vue-cli3配置favicon.ico和title的流程
Oct 27 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
apache+mysql+php+ssl服务器之完全安装攻略
2006/09/05 PHP
php实现的仿阿里巴巴实现同类产品翻页
2009/12/11 PHP
php面向对象与面向过程两种方法给图片添加文字水印
2015/08/26 PHP
PHP中key和current,next的联合运用实例分析
2016/03/29 PHP
PHP通过调用新浪API生成t.cn格式短网址链接的方法详解
2019/02/20 PHP
一段效率很高的for循环语句使用方法
2007/08/13 Javascript
jquerymobile checkbox及时刷新才能获取其准确值
2012/04/14 Javascript
js获取html参数及向swf传递参数应用介绍
2013/02/18 Javascript
js 显示base64编码的二进制流网页图片
2014/04/04 Javascript
基于javascript代码实现通过点击图片显示原图片
2015/11/29 Javascript
BootStrap 智能表单实战系列(二)BootStrap支持的类型简介
2016/06/13 Javascript
Bootstrap基本样式学习笔记之标签(5)
2016/12/07 Javascript
vue实现图片滚动的示例代码(类似走马灯效果)
2018/03/03 Javascript
javascript设计模式 ? 解释器模式原理与用法实例分析
2020/04/17 Javascript
JavaScript对象字面量和构造函数原理与用法详解
2020/04/18 Javascript
python计算最小优先级队列代码分享
2013/12/18 Python
Python中的Numpy入门教程
2014/04/26 Python
以视频爬取实例讲解Python爬虫神器Beautiful Soup用法
2016/01/20 Python
Python基础语法(Python基础知识点)
2016/02/28 Python
Python解析json文件相关知识学习
2016/03/01 Python
Python网络爬虫出现乱码问题的解决方法
2017/01/05 Python
Python 获取 datax 执行结果保存到数据库的方法
2019/07/11 Python
css3实现超立体3D图片侧翻倾斜效果
2014/04/16 HTML / CSS
Lampegiganten丹麦:欧洲领先的照明网上商店
2018/04/25 全球购物
大学生实习鉴定评语
2014/04/25 职场文书
村级四风对照检查材料
2014/08/24 职场文书
2014教师专业技术工作总结
2014/12/03 职场文书
参观邀请函范文
2015/02/02 职场文书
2015年社区精神文明工作总结
2015/05/26 职场文书
2016三八妇女节校园广播稿
2015/12/17 职场文书
创业计划书介绍
2019/04/24 职场文书
Python用tkinter实现自定义记事本的方法详解
2022/03/31 Python
mysql的单列多值存储实例详解
2022/04/05 MySQL
python中字符串String及其常见操作指南(方法、函数)
2022/04/06 Python
MySQL提取JSON字段数据实现查询
2022/04/22 MySQL
python 单机五子棋对战游戏
2022/04/28 Python