Я, честно говоря, не знаю, что происходит.Конечно, вещь с плавающей точкой очевидна, но я не понимаю, почему переупорядочение уравнения должно изменить ситуацию.Я экспериментировал, используя слегка упрощенную версию уравнения, меняя значения и перемещая вещи.
Уравнение 1 и У.2 совпадают с ОП, а У.3 эквивалентно Уравнению 1 благодаря предпочтению оператора (см. ?Syntax
).*
и /
оцениваются до +
и -
, за исключением того, что они оцениваются слева направо, а круглые скобки разрешаются от внутреннего к внешнему.Таким образом, в уравнениях 1 и 3 порядок составляет -
/
*
+
, а в уравнении 2 - -
*
/
+
.
a <- 100
b <- 100
c <- 0.1
e <- 0.3
r1 <- a / b * (e - c) + c # [1]
r2 <- (e - c) * a / b + c # [2]
r3 <- (e - c) * (a / b) + c # [3]
r1 == r2 # FALSE
r1 == r3 # TRUE
sprintf("%.20f", c(r1, r2, r3))
# "0.29999999999999998890" "0.30000000000000004441" "0.29999999999999998890"
Понятно, что точное значение зависит от порядка операций, хотя в чисто арифметических терминах это не должно иметь значения (они ассоциативны).Но порядок имеет значение только тогда, когда вы используете некоторые конкретные значения.Если вы установите a
и b
на 10, скажем, или установите c
на 0,2, значения будут идентичны.Я догадываюсь, что это вызвано делением, выполняемым в целочисленном режиме в уравнении (1), и режимом с плавающей запятой в уравнении (2), во втором вводятся ошибки округления, в отличие от первого (зависит от начальных значений).Разумеется, реальное сообщение о том, с чем связан Маркус , связан с , вам нужно проявлять особую осторожность при сравнении чисел с плавающей запятой, но было бы неплохо иметь определенное объяснение этого точного поведения.