3*1.1为什么等于3.3000000000000003?

js发展那么多年了,为什么都不去解决这个问题呢?

如果说无法解决,有人能简单说明一下为什么无法解决这样的问题吗?

阅读 4.1k
5 个回答

https://segmentfault.com/a/11...

Number采用的时IEEE 754 64位双精度浮点数编码。而浮点数表示方式具有以下特点:
浮点数可表示的值范围比同等位数的整数表示方式的值范围要大得多;
浮点数无法精确表示其值范围内的所有数值,而有符号和无符号整数则是精确表示其值范围内的每个数值;
浮点数只能精确表示m*2e的数值;
当biased-exponent为2e-1-1时,浮点数能精确表示该范围内的各整数值;
当biased-exponent不为2e-1-1时,浮点数不能精确表示该范围内的各整数值。

事实上把全宇宙的硬盘加起来也存不了0.1的二进制。

是时候那祭出大神的网站了,里边有详细的原因说明。

http://0.30000000000000004.com

域名难记?随便一个c系(php、java、c、c++、javascript)语言,计算一下就可以了。

js代码:

location.href = 'http://' + (0.1+0.2) + '.com';

你需要math.js php 有对应的bcmath

程式语言内建对于浮点数的精度问题。这个问题我不是专家,但可以分享一些看法。

首先你要理解几点,在JavaScript语言中的数值(Number)类型是什么?它也只有一种数值的类型,没有整数、浮点数、双精度浮点数的设计。标准上是说这数值(Number)类型,是使用双精度浮点数(double)使用64位元(8位元组)的设计,但是在引擎的内部实作实际上它会知道是什么也会区分,为什么要区分,理由当然就是为了执行时的效率与资源使用。

高精度浮点数的数学运算是有代价的,只有在某些情况下,我们会需要高精度浮点数的数学运算,或是非常多位数的数学运算,通常是在科学上的运算。JavaScript语言的设计本身就不是为了这些运算而设计的,它是个动态类型的脚本语言,而且一开始是在有限的浏览器环境下才能执行。

当然,你也可以说,像这么简单的0.3 - 0.10.2 + 0.1都算不好,这算那门子程式语言,不见得用什么高超的例子来测试,这两个例子就可以看得到。这也不算JavaScript本身的问题,许多程式语言中都有类似的问题,

听过python吧,下面是python中0.2 + 0.1的结果:

>>> 0.1 + 0.2
0.30000000000000004

听过ruby吧,下面是ruby中0.2 + 0.1的结果:

puts 0.1 + 0.2
0.30000000000000004

上面两个脚本语言可能没用过,那么Java大牛应该有听过了,下面是Java中0.2 + 0.1的结果:

System.out.print(0.1+0.2);
0.30000000000000004

当然,我上面举的例子只是未经过再进一步定义资料类型的例子,不同的程式语言有不同的资料类型定义,用于处理高精度数字的问题。这些例子还可以举出很多,目的是要说明JavaScript并非是想像中那么设计不良的程式语言,拿你的例子去套到这些程式语中,也是类似的情况。所以,并不是所谓发展这么久了,不求上进的问题,而是这个问题存在了很久,它自然有别的方式来解决这些问题,下面再来谈谈如何面对与解决这些问题。

第一种方式是类型,在js中不像其他程式语言有内附的高精度数字类型,所以你需要扩充,函式库很多可以参考使用,BigDecimal、decimal.js、big.js等等,为什么我讲类型而不是单个物件或函式库而已,因为高精度的数字运算,大概都不能再使用你原先使用于数字的+-*/%符号来运算,而是要用整个类型所能提供的方法,额外作运算才行。这整个函式库都是在考量效率、资源的消耗等等。当然他们也有计算的极限,不可能能计算永无止尽的数字位数。这个方式适合你真的需要科学上的、金钱上的(例如算股票、利息之类),或是真的是高精度的数字运算。

第二种方式是格式化你的运算结果,如果这能达成你的需求的话,例如你只需要小数点后两位,那么可以用格式化的方法来呈现即可,至少一般简单的运算是可行的。

第三种就是不要用浮点数,只用整数值。四舍五入也是一种解决方案,能预测的准的话也可以自己看需求写函式来求值。整数值可以让你的开发日子更轻松美好,整数值对js引擎来说,其实是飞快的。

如果你对浮点数想要进一步理解,或是看各种程式语言中的基本解决方了,我会推荐看这篇: http://floating-point-gui.de/或是它的github: https://github.com/brazzy/flo...

推荐问题
宣传栏