根据Is floating point math broken? ,我知道 0.1 不能精确地表示 float ,并且会四舍五入到某些值。
根据Is hardcode float precise if it can be represented by binary format in IEEE 754? ,一些具有整数值的数字(例如:1,2,10...)可以完美地表示(没有舍入错误)。
所以我的问题是,如果 x 、y 和 a 是整数值,那么 x/y 是否舍入为与 (x * a)/(y * a) 相同的值?
例如,1/10 是否舍入为与 10/100 以及 123/1230 相同的值?
最佳答案
numbers with integers values (e.g.:1,2,10...) can be represented perfectly (no rounding errors)
仅在 -Number.MAX_SAFE_INTEGER - 1
(-9,007,199,254,740,992) 到 Number.MAX_SAFE_INTEGER + 1
(9,007,199,254,740,992) 范围内(含)。超出该范围,整数确实会四舍五入:
var n = Number.MAX_SAFE_INTEGER;
console.log("n =", n);
console.log("n + 1 =", n + 1);
console.log("n + 2 =", n + 2); // rounds
For example, does 1/10 rounds to the values same as 10/100, as well as 123/1230?
对于这些类型的示例,我认为您最终会得到相同的值,是的。但与此相关的两件事值得一提:
我认为 JavaScript 不允许这样做,但某些使用 IEEE-754 数字的实现允许计算中的中间值比格式所能容纳的精度更高,并且因此通过计算的输入和输出。 [例如,Java 具有“宽松”和“严格”浮点(
strictfp
关键字和相关运行时标志),其中“宽松”允许更精确的中间值,而严格则不允许(因此,在“松散”的 FP 环境和足够复杂的计算中,如果实现以更精确的形式保存中间值,则结果可能与计算的每个阶段都通过舍入处理时略有不同格式的限制。但同样,除了与 some trigonometric functions 相关之外,我在 JavaScript 规范中找不到任何允许这样做的内容,而且我认为即使适用,也不适用于上面的简单除法示例。如上所述,小数的大小会影响它是否被精确保存(0.1 不是,1 是,9,007,199,254,740,993 不是)。但在上述范围内的整数内,由于它们都被完美地保留,所以输入将正是它们看起来的样子。
If
x
,y
anda
are number with integer values, doesx/y
rounds to the same value as(x*a)/(y*a)
?
这是一个稍微不同的问题,它取决于数字的大小。如果 x*a 的结果或 y*a 的结果的值超出了本答案开头讨论的范围,您可能会得到不同的结果那些表情。因此,对于较大的整数,可能不会,它们可能不会有相同的结果:
var x = 945127356192545;
var y = 123456789012345;
var a = 27;
var r1 = x/y;
console.log("x/y =", r1);
var r2 = (x*a)/(y*a);
console.log("(x*a)/(y*a) =", r2);
console.log("same?", r1 == r2);
关于javascript - 如果 x、y 和 a 是具有整数值的数字,则 x/y 是否舍入为与 (x*a)/(y*a) 相同的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48900972/