javascript为什么 0.1 + 0.2 = 0.30000000000000004
来源:互联网 发布:酒店美工是做些什么 编辑:程序博客网 时间:2024/06/02 02:16
如果我问你 0.1 + 0.2 等于几?你可能会送我一个白眼,0.1 + 0.2 = 0.3 啊,那还用问吗?连幼儿园的小朋友都会回答这么小儿科的问题了。但是你知道吗,同样的问题放在编程语言中,或许就不是想象中那么简单的事儿了。
不信?我们先来看一段 JS。
var numA = 0.1;var numB = 0.2;alert( (numA + numB) === 0.3 );
执行结果是 false。没错,当我第一次看到这段代码时,我也理所当然地以为它是 true,但是执行结果让我大跌眼镜,是我的打开方式不对吗?非也非也。我们再执行以下代码试试就知道结果为什么是 false 了。
var numA = 0.1;var numB = 0.2;alert( numA + numB );
原来,0.1 + 0.2 = 0.30000000000000004。是不是很奇葩?其实对于浮点数的四则运算,几乎所有的编程语言都会有类似精度误差的问题,只不过在 C++/C#/Java 这些语言中已经封装好了方法来避免精度的问题,而 JavaScript 是一门弱类型的语言,从设计思想上就没有对浮点数有个严格的数据类型,所以精度误差的问题就显得格外突出。下面就分析下为什么会有这个精度误差,以及怎样修复这个误差。
首先,我们要站在计算机的角度思考 0.1 + 0.2 这个看似小儿科的问题。我们知道,能被计算机读懂的是二进制,而不是十进制,所以我们先把 0.1 和 0.2 转换成二进制看看:
0.1 => 0.0001 1001 1001 1001…(无限循环)
0.2 => 0.0011 0011 0011 0011…(无限循环)
双精度浮点数的小数部分最多支持 52 位,所以两者相加之后得到这么一串 0.0100110011001100110011001100110011001100110011001100 因浮点数小数位的限制而截断的二进制数字,这时候,我们再把它转换为十进制,就成了 0.30000000000000004。
原来如此,那怎么解决这个问题呢?我想要的结果就是 0.1 + 0.2 === 0.3 啊!!!
有种最简单的解决方案,就是给出明确的精度要求,在返回值的过程中,计算机会自动四舍五入,比如:
var numA = 0.1;var numB = 0.2;alert( parseFloat((numA + numB).toFixed(2)) === 0.3 );
但是明显这不是一劳永逸的方法,如果有一个方法能帮我们解决这些浮点数的精度问题,那该多好。我们来试试下面这个方法:
Math.formatFloat = function(f, digit) { var m = Math.pow(10, digit); return parseInt(f * m, 10) / m;}var numA = 0.1;var numB = 0.2;alert(Math.formatFloat(numA + numB, 1) === 0.3);
这个方法是什么意思呢?为了避免产生精度差异,我们要把需要计算的数字乘以 10 的 n 次幂,换算成计算机能够精确识别的整数,然后再除以 10 的 n 次幂,大部分编程语言都是这样处理精度差异的,我们就借用过来处理一下 JS 中的浮点数精度误差。
如果下次再有人问你 0.1 + 0.2 等于几,你可要小心回答咯 :-)
请执行一下,为什么都不执行就回答呢?
0.1+0.2=0.30000000000000004 为什么?
我知道了
浮点数”不是“实数”,浮点数有最大表示范围,在表示范围内用最接近实数的浮点数可以表示数来表示,比如
0.1是实数,意味着0.10000000…… 都是0.1,而double无法精确表示0.1,但它能精确表示 +0.1000000000000000055511151231257827021181583404541015625 ,所以它用 +0.1000000000000000055511151231257827021181583404541015625 来表示 0.1,同样:
0.1 <--> 0.1000000000000000055511151231257827021181583404541015625
0.2 <--> 0.200000000000000011102230246251565404236316680908203125
0.3 <--> 0.299999999999999988897769753748434595763683319091796875
而 0.1000000000000000055511151231257827021181583404541015625 + 0.200000000000000011102230246251565404236316680908203125 的结果也是浮点数无法精确表示的,于是它用最接近的 +0.3000000000000000444089209850062616169452667236328125 来表示。
- javascript为什么 0.1 + 0.2 = 0.30000000000000004
- 为什么 javascript 中 0.1 + 0.2 !== 0.3 为 True
- javascript: ++[[]][+[]]+[+[]] = 10 ?为什么
- 为什么“0.1+0.2=0.30000000000000004”?
- 【javascript黑魔法】为什么 ++[[]][+[]]+[+[]] = 10?
- 为什么要学JavaScript?
- 为什么要使用 JavaScript
- 为什么要使用 JavaScript
- 为什么学习JavaScript?
- 为什么要学javascript
- javaScript入门--为什么学?
- 为什么需要有JavaScript
- 为什么会有JavaScript???
- javascript 代码alert([] ==![]);为什么弹出结果为true?
- 疑问:为什么要使用href=”javascript:void(0);”?
- 为什么要使用href=”javascript:void(0);”(未完待续)
- 为什么要使用href="javascript:void(0);"
- 轻松学习JavaScript一:为什么学习JavaScript
- 有符号数和无符号数
- 织梦dedecms怎么调用自定义联动类型
- Codeforces 645E Intellectual Inquiry (dp不同子序列计数)
- dede首页缩略图不变形的解决方法
- 织梦商品模型多缩略图实现方法,织梦多缩略图实现方法
- javascript为什么 0.1 + 0.2 = 0.30000000000000004
- [转]window.opener用法
- flask bbs 社交网站开发
- innerHTML与jquery里的html()区别介绍
- 图片压缩
- DEDEcms织梦ping插件@chinajkys.com
- 一年三 季 醋 泡 姜
- js 怎样从子窗口调用父窗口的方法
- Warning: Cannot modify header information - headers already sent by....详解