跟我学习javascript的浮点数精度


Posted in Javascript onNovember 16, 2015

大多数编程语言都有几种数值型数据类型,但是JavaScript却只有一种。你可以使用typeof 运算符查看数字的类型。不管是整数还是浮点数,JavaScript都将它们简单地归类为数字。

typeof 17; //number
typeof 98.6; //number
typeof -21.3; //number

事实上,JavaScript中所有的数字都是双精度浮点数。这是由IEEE754标准制定的64位编码数字——即“doubles”。如果这一事实使你疑惑JavaScript是如何表示整数的,请记住,双精度浮点数能完美地表示高达53位精度的整数。从?9 007 199 254 740 992(?253)到9 007 199 254 740 992(253)的所有整数都是有效的双精度浮点数。因此,尽管JavaScript中缺少明显的整数类型,但是完全可以进行整数运算。
大多数的算术运算符可以使用整数、实数或两者的组合进行计算。

0.1 * 0.9; //0.19
-99 + 100; //1
21- 12.3; //8.7
2.5 /5; //0.5
21%8; //5

然而位算术运算符比较特殊。JavaScript不会直接将操作数作为浮点数进行运算,而是会将其隐式地转换为32位整数后进行运算。(确切地说,它们被转换为32位大端(big-endian)的2的补码表示的整数。)以按位或运算表达式为例:

8|1; //9

看似简单的表达式实际上需要几个步骤来完成运算。如前所述,JavaScript中的数字8和1都是双精度浮点数。但是它们也可以表示成32位整数,即32位0、1的序列。整数8表示为32位二进制序列如下所示:

00000000000000000000000000001000

你自己也可以使用数字类型的toString方法来查看:

(8).toString(2)  //"1000"

toString方法的参数指定了其转换基数,此例子以基数2(即二进制)表示。结果值省略了左端多余的0(位),因为它们并不影响最终值。
整数1表示为32位二进制如下所示:

00000000000000000000000000000001

按位或运算表达式合并两个比特序列。只要参与运算的两位比特中任意一位为1,运算结果的该位就为1。以位模式表示的结果如下:

00000000000000000000000000001001

这个序列表示整数9。你可以使用标准的库函数parseInt验证,同样以2作为基数:

parseInt("1000", 2); //9

(同样,前导0位是不必要的,因为它们并不影响运算结果。)
所有位运算符的工作方式都是相同的。它们将操作数转换为整数,然后使用整数位模式进行运算,最后将结果转换为标准的JavaScript浮点数。一般情况下,JavaScript引擎需要做些额外的工作来进行这些转换。因为数字是以浮点数存储的,必须将其转换为整数,然后再转换回浮点数。然而,在某些情况下,算术表达式甚至变量只能使用整数参与运算,优化编译器有时候可以推断出这些情形而在内部将数字以整数的方式存储以避免多余的转换。

关于浮点数的最后警示是,你应该对它们保持时刻警惕。浮点数看似熟悉,但是它们是出了名的不精确。甚至一些看起来最简单的算术运算都会产生不正确的结果。

0.1+0.2; 0.300000000000004

尽管64位的精度已经相当高了,但是双精度浮点数也只能表示一组有限的数字,而不能表示所有的实数集。浮点运算只能产生近似的结果,四舍五入到最接近的可表示的实数。当你执行一系列的运算,随着舍入误差的积累,运算结果会越来越不精确。舍入也会使我们通常所期望的算术运算定律产生一些出人意料的偏差。例如,实数满足结合律,这意味着,对于任意的实数x,y,z,总是满足(x + y) + z = x + (y + z)。

然而,对于浮点数来说,却并不总是这样。

(0.1+0.2)+0.3; //0.60000000000000001
0.1+(0.2+ 0.3); //0.6

浮点数权衡了精度和性能。当我们关心精度时,要小心浮点数的局限性。一个有效的解决方法是尽可能地采用整数值运算,因为整数在表示时不需要舍入。当进行货币相关的计算时,程序员通常会按比例将数值转换为最小的货币单位来表示再进行计算,这样就可以以整数进行计算。例如,如果上面的计算是以美元为单位,那么,我们可以将其转换为整数表示的美分进行计算。

(10+20)+30; //60
10+ (20+30); //60

对于整数运算,你不必担心舍入误差,但是你还是要当心所有的计算只适用于?253~253的整数。

提示

  • JavaScript的数字都是双精度的浮点数。
  • JavaScript中的整数仅仅是双精度浮点数的一个子集,而不是一个单独的数据类型
  • 位运算符将数字视为32位的有符号整数。

以上就是介绍的javascript的浮点数,我们要时刻注意浮点运算中的精度陷阱,希望这篇文章对大家的学习有所帮助。

Javascript 相关文章推荐
一款js和css代码压缩工具[附JAVA环境配置方法]
Apr 16 Javascript
Javascript中的isNaN函数使用说明
Nov 10 Javascript
js调用webservice中的方法实现思路及代码
Feb 25 Javascript
js动态为代码着色显示行号
May 29 Javascript
jQuery实现平滑滚动页面到指定锚点链接的方法
Jul 15 Javascript
Angular 中 select指令用法详解
Sep 29 Javascript
jstree创建无限分级树的方法【基于ajax动态创建子节点】
Oct 25 Javascript
微信小程序 下拉列表的实现实例代码
Mar 08 Javascript
javascript+html5+css3自定义提示窗口
Jun 21 Javascript
解决iView中时间控件选择的时间总是少一天的问题
Mar 15 Javascript
vue柱状进度条图像的完美实现方案
Aug 26 Javascript
小程序按钮避免多次调用接口和点击方案实现(不用showLoading)
Apr 15 Javascript
跟我学习javascript的严格模式
Nov 16 #Javascript
javascript中tostring()和valueof()的用法及两者的区别
Nov 16 #Javascript
关于javascript中dataset的问题小结
Nov 16 #Javascript
javascript入门教程基础篇
Nov 16 #Javascript
JavaScript中函数表达式和函数声明及函数声明与函数表达式的不同
Nov 15 #Javascript
浅谈JavaScript中的对象及Promise对象的实现
Nov 15 #Javascript
javascript 中的 delete及delete运算符
Nov 15 #Javascript
You might like
php数据库密码的找回的步骤
2011/01/12 PHP
基于initPHP的框架介绍
2013/04/18 PHP
Zend Framework教程之Zend_Layout布局助手详解
2016/03/04 PHP
php反射类ReflectionClass用法分析
2016/05/12 PHP
PHP基于双向链表与排序操作实现的会员排名功能示例
2017/12/26 PHP
php+js实现裁剪任意形状图片
2018/10/31 PHP
smarty模板的使用方法实例分析
2019/09/18 PHP
对采用动态原型方式无法展示继承机制得思考
2009/12/04 Javascript
基本jquery的控制tabs打开的数量的代码
2010/10/17 Javascript
Jquery的each里用return true或false代替break或continue
2014/05/21 Javascript
js闭包实例汇总
2014/11/09 Javascript
深入理解JavaScript系列(22):S.O.L.I.D五大原则之依赖倒置原则DIP详解
2015/03/05 Javascript
jQuery实现预加载图片的方法
2015/03/17 Javascript
javascript中Date()函数在各浏览器中的显示效果
2015/06/18 Javascript
javascript实现数组内值索引随机化及创建随机数组的方法
2015/08/10 Javascript
Node.js 数据加密传输浅析
2016/11/16 Javascript
Vue数据驱动模拟实现4
2017/01/12 Javascript
微信小程序左滑删除效果的实现代码
2017/02/20 Javascript
React 高阶组件入门介绍
2018/01/11 Javascript
Vue.js点击切换按钮改变内容的实例讲解
2018/08/22 Javascript
vue.js 实现a标签href里添加参数
2019/11/12 Javascript
微信小程序canvas动态时钟
2020/10/22 Javascript
ant design vue中日期选择框混合时间选择器的用法说明
2020/10/27 Javascript
Vue 打包的静态文件不能直接运行的原因及解决办法
2020/11/19 Vue.js
[01:14:35]DOTA2上海特级锦标赛B组资格赛#1 Alliance VS Fnatic第一局
2016/02/26 DOTA
python实现顺时针打印矩阵
2019/03/02 Python
使用python将最新的测试报告以附件的形式发到指定邮箱
2019/09/20 Python
Python面向对象之私有属性和私有方法应用案例分析
2019/12/31 Python
Python实现新型冠状病毒传播模型及预测代码实例
2020/02/05 Python
python GUI库图形界面开发之PyQt5选项卡控件QTabWidget详细使用方法与实例
2020/03/01 Python
微信浏览器左上角返回按钮拦截功能
2017/11/21 HTML / CSS
三只松鼠官方旗舰店:全网坚果销售第1
2017/11/25 全球购物
一套Java笔试题
2016/08/20 面试题
报纸媒体创意广告词
2014/03/17 职场文书
毕业实习感受与体会
2015/05/26 职场文书
创业计划书之餐饮馄饨店
2019/07/18 职场文书