Javascript模(%)行为奇怪
我正在计算(6.6%1.1)。我希望这是0,但我得到1.099999996。您可以在javascript控制台中轻松地重现这一点。我猜这是一个内部取整错误?如何解决此问题?运算符对非整数值的作用方式并不明显。表情Javascript模(%)行为奇怪,javascript,modulo,Javascript,Modulo,我正在计算(6.6%1.1)。我希望这是0,但我得到1.099999996。您可以在javascript控制台中轻松地重现这一点。我猜这是一个内部取整错误?如何解决此问题?运算符对非整数值的作用方式并不明显。表情 n % d JavaScript所做的是找到小于n/d的最大整数(我称之为q,以反映规范)。然后它计算乘积d*q,结果是差值n-(d*q) (为了简单起见,我忽略了符号问题。) 你考虑整数余数的想法是有道理的:如果n和d是整数,那么上面的公式就完全有道理了。采取17%3。好的17/3
n % d
JavaScript所做的是找到小于n/d
的最大整数(我称之为q
,以反映规范)。然后它计算乘积d*q
,结果是差值n-(d*q)
(为了简单起见,我忽略了符号问题。)
你考虑整数余数的想法是有道理的:如果n
和d
是整数,那么上面的公式就完全有道理了。采取17%3
。好的17/3
是5。有些东西,所以q
是5
,其余的是17-(5*3)
或2
在您的例子中,由于使用标准IEEE 754浮点,6.6/1.1
不是6
,这个过程变得有点混乱;由于用二进制浮点表示十进制浮点值的精度,它只比6
小一点点。因此,当计算q
时,结果是5
,而不是6
。因此答案是6-(5*1.1)
,或者6-5.5
,这(同样是不精确的)比1.1
JavaScript使用IEEE双精度来存储浮点数,所以6.6是6.599999(我猜?)。您可以使用
(66 % 11)/10
为了避免错误。正如其他人所指出的,您可以看到IEEE-754浮点数的舍入效应。这不是JavaScript所独有的:
$ python
>>> 6.6 % 1.1
1.0999999999999992
处理浮点问题的方法是使用任意精度的数学库:
例如,使用:
回答真正的问题:不应该对非整数使用模运算符。问题是6.6/1.1
不是6.0
,而是5.999999999999999
,然后将其四舍五入到5
,而不是6
,因此差异是6.6-5.0*1.1=1.1
,而不是6.6-6.0*1.1=0
。你真的需要模运算符吗?通常,对于非自然数(或至少是整数)最好避免使用它;它有定义良好的语义。问题是,大多数人永远不会猜测这些语义是什么,而不去寻找它,甚至找出它们为什么是这样的挑战。
x = new Big(6.6)
// Big {s: 1, e: 0, c: Array[2]}
y = new Big(1.1)
// Big {s: 1, e: 0, c: Array[2]}
x.mod(y).toString()
// "0"