如果 x、y 和 a 是具有整数值的数字,x/y 是否舍入为与 (x*a)/(y*a) 相同的值?

If x, y, and a are numbers with integer values, does x/y round to the same value as (x*a)/(y*a)?

根据Is floating point math broken?,我知道0.1不能精确地表示为浮点数,会四舍五入到一些值。

根据,一些具有整数值的数字(例如: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?

对于这些类型的示例,我认为您最终会得到相同的值,是的。但是有两件事值得一提:

  1. 我认为 JavaScript 不允许这样做,但一些使用 IEEE-754 数字的实现允许在计算中使用 中间值比格式更精确,因此计算的输入和输出更精确。 [Java,例如,同时具有 "loose" 和 "strict" floating-point(strictfp 关键字和相关的运行时标志),其中 "loose" 允许中间更精确和严格的值(为了互操作性)。] 所以在 "loose" FP 环境和 sufficiently-complex 计算中,如果实现以 more-precise 形式保存中间值,结果如果计算的每个阶段都根据格式的约束四舍五入处理,则可能会略有不同。但同样,我在 JavaScript 规范中找不到任何允许与 some trigonometric functions 相关的内容,而且我认为这不适用于上面的简单除法示例,即使它适用。

  2. 如上所述,小数的大小会影响它是否精确(0.1 不是,1 是,9,007,199,254,740,993 不是)。但在上面讨论的范围内的整数内,由于它们都保持完美,输入将完全像它们看起来的那样。

If x, y and a are number with integer values, does x/y rounds to the same value as (x*a)/(y*a)?

这是一个略有不同的问题,它取决于数字的大小。如果 x*ay*a 的结果使值超出本答案开头讨论的范围,则这些表达式可能会得到不同的结果。所以对于 large-ish 整数,可能不是,它们可能不会有相同的结果:

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);