-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Day2 - 0.1 + 0.2 === 0.3 嘛?为什么?怎么解决? #2
Comments
精度丢失可能出现在进制转换和对阶运算中 JavaScript 使用 Number 类型来表示数字(整数或浮点数),遵循 IEEE 754 标准,通过 64 位来表示一个数字(1 + 11 + 52) 1 符号位,0 表示正数,1 表示负数 s 最大安全数字:Number.MAX_SAFE_INTEGER = Math.pow(2, 53) - 1,转换成整数就是 16 位,所以 0.1 === 0.1,是因为通过 toPrecision(16) 去有效位之后,两者是相等的。 高逼格ES6 |
浮点数的比较方法错了,正确的方法是比较绝对值是否在JS提供的最小精度范围内
JS 中的 Number 类型基本符合 IEEE 754-2008 规定的双精度浮点数规则,根据浮点数的定义,非整数的 Number 类型无法用 ==(=== 也不行) 来比较。
浮点数运算的精度问题导致等式左右的结果并不是严格相等,而是相差了个微小的值。 |
这是浮点数精度丢失的问题,经常出现在进制转换的时候 javascript 使用的是 IEEE-745 浮点数表示法,浮点数在计算机中是使用二进制进行存储,呈现给用户时使用十进制数,当 0.1 和 0.2 转换成二进制时,会出现无限循环,而双精度浮点数的小数部分最多支持 52 位,超过 52 位的部分或被截断,计算机就是使用被截断后的二进制数进行计算,然后在转换成十进制数返回给用户,这个过程就已经出现误差了,而误差的部分就是被计算机截断的部分导致的 解决方法有两种: |
不等于,这是由于 JS 存在精度丢失问题。 计算机存储小数的方法是将浮点数转化为对应的二进制存储,采用的标准是 IEEE 754。 1 个符号位,表示正负号; 由于在 解决方法: |
回答不等于 原因这是由于 JS 存在精度丢失问题。 解决思路解决本题方法 1:可以将小数* 解决同类型题方法:将数字转换为字符串,字符串逐位相加得到精确的结果; 最后感谢 @liangle @rachern @bianzheCN 让我学到了 Number.EPSILON |
这是浮点数的精度问题,JavaScript中的数字都是保存为双精度浮点数,在十进制转化成二进制的时候,不能被2除尽的数都无法精确表达,然后进行了截取。简单来说就是十进制转二进制计算这个过程是不完全准确的。计算时可以放大10的n次方转换成整数再进行计算。 |
0.1 + 0.2 是不等于 0.3的,这是浮点数的精度的问题; |
|
在js中,0.1 + 0.2不等于0.3。 |
|
肯定是不等于的
解决方法
|
结论:0.1 + 0.2 !=0.3 原因:JavaScript中的数字,是以双精浮点数在计算机中进行储存的,为二进制,占用64bit,既用64位数来表示一个数值。 而0.1,0.2转化为二进制时,会出现无限循环的问题,所以由于位数限制会进行截断,而用截断过后的二进制数转换回十进制表示出来,就会自然出现精度缺失。 解决办法:
|
不等,是因为 IEEE 754
小数在计算机中的存储方式: 具体原因0.1和0.2转换成二进制后是一个无限循环的二进制数,而尾数位只能存储52位有效数字,所以这个时候无法被存储的后续部分就进行了取舍,取舍的规则是在 IEEE 754中定义的。 为什么无限循环转换二进制的过程:
4 => 4%2 = 2 余 0
0.5 => 0.5*2 = 1 取整 1 0.1 => 0.12 = 0.2 取整 0 浮点数的舍入任何有效数上的运算结果,通常都存放在较长的寄存器中,当结果被放回浮点格式时,必须将多出来的比特丢弃。有多种方法可以用来执行舍入作业,实际上IEEE标准列出4种不同的方法:
00011001100110011001100110011... (0011)循环 0(0011)(0011)(0011)(0011)(0011)(0011)(0011)(0011)(0011)(0011)(0011)(0011)(0011)(0011) = 0(0011)(0011)(0011)(0011)(0011)(0011)(0011)(0011)(0011)(0011)(0011)(0011)(0011) 所以 0.1 和 0.2 存储后就发生了精度丢失的问题,从而相加之后的结果不严格等于 0.3。 解决方案
|
十进制转二进制方法是"乘以2取整,顺序输出”; 计算机存储浮点数,会被转为二进制,0.1和0.2会被转为无限不循环小数,直到存满规范的浮点数存储空间,相加之后,尾部大小溢出,取和,最终变成0.30000000000000004 解决办法,使用第三方库,math.js 或者big.js,自己来计算的话也可以先将浮点类型转换为整形,最终再对应处理相加之后转回浮点型。 昨天写错地方了,挪过来 |
JS中的所有数字均用浮点数值表示,其采用IEEE 754标准定义64位浮点格式表示数字。 其表示方式为1位符号位,11位指数位,52位小数位。 js的表示的数字范围是由这些64位组成的。由于0.1和0.2用二进制表示是无限循环小数,而JS的浮点数计数标准中浮点数小数位只有52位,所以会有精度的丢失。我们知道在10进制计算过程中我们是四舍五入,而在二进制中只有0和1,所以是1进0舍,所以0.1+0.2的结果的偏差会照成实际结果要比0.3略大。 |
不等于 |
The text was updated successfully, but these errors were encountered: