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

我正在计算(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
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"