提问人:Curtis 提问时间:3/29/2023 最后编辑:Curtis 更新时间:3/29/2023 访问量:48
Math.round(intA/intB) 是否总是在每台设备上返回相同的结果?
Will Math.round(intA/intB) always return the same on every device?
问:
我担心像 7/2 这样的东西可能会在某些计算机上变成 3.499999999 而不是 3.5,然后四舍五入为 3 而不是 4。这可能吗?
我需要每台计算机都精确地重新运行相同的数学运算。这是我唯一一次有浮点数:Math.round(intA/intB)
答:
3赞
ShadowRanger
3/29/2023
#1
您的问题分为两部分:
- 每个可表示的整数值除以 精确到 的倍数吗?
2
.5
- 会随身携带吗?
Math.round
两者的答案都应该是肯定的(尽管显然实现者可以做一些奇怪的事情)。具体说来:
IEE-754 二进制浮点值(JS 是以 binary64 形式实现的)使用基于 2 幂的比例因子;因此,任何可表示的整数值都可以除以而不会造成精度损失;要么是均匀除法(不需要比例因子),要么是奇数,比例因子用于内部存储,基本上是“原始值除以”。
Number
Number
2
2**1
-
如果小数部分正好是 0.5,则参数将沿 +∞ 方向舍入到下一个整数。
在这两个保证之间,您无需担心; 将永远是精确的,并且将永远是.只有当你除以非 2 的幂(或巨大的 2 的幂)时,或者你除以不是精确整数的东西时,错误才会悄悄出现。7/2
3.5
Math.round(7/2)
4
如果你正在做一些在 IEEE-754 二进制浮点中产生不精确结果的事情,它将是不精确的,但它应该是可移植的不精确的;JS 不是 C,该规范明确要求双精度 64 位二进制格式 IEEE 754,而不是“无论处理器碰巧提供什么”,因此您不必担心提供与 IEEE-754 不兼容的浮点的深奥硬件(如果硬件不支持它,任何兼容的 JS 引擎都需要在软件中实现它)。
评论
0赞
Curtis
3/29/2023
等等,所以我可能不得不担心像 9/6 这样的事情?我实际上正在做一些 RandomInt/n,其中 n 从 2 到 9 循环。所以 6 是唯一不是 2 的幂并且可以给出 x.5 的 n
0赞
ShadowRanger
3/29/2023
@Curtis:我相信,如果它能被除 2 个因素的幂之外的所有因素平均整除,你应该没问题。所以抵消一个 ,留下 ,这是无损的。当非 2 次幂除数触发无法以 2 为基数表示的值的近似值时,就会出现问题。因此,如果您通过 (这在逻辑上只是 ),第一步将不精确,因此结果实际上可能不是(我没有检查)。但是,如果它是一个文字整数值除以 ,你就很清楚了。9 / 6
3
3 / 2
9
9 / 27 * 9 * 3
9
9
9
6
0赞
Eric Postpischil
3/29/2023
关于“不精确的结果”:问题在于准确性(获得值的忠实度)而不是精确度(表示值的精细度)。IEEE-754 中的所有普通数字都具有相同的精度。
评论
7/2
2