Ответ 1
"Почему" этого в основном сводится к тому, что часто при работе с данными float
может использоваться внутреннее представление, которое имеет большую точность, чем указано для float
или double
. Это явно учитывается в спецификации виртуальной исполнительной системы (VES) (раздел 12 раздела раздел I):
числа с плавающей запятой представлены с использованием внутренней с плавающей запятой тип. В каждом таком случае номинальный тип переменной или выражения равен либо
float32
, либоfloat64
, но его значение может быть представлено внутри с дополнительным диапазоном и/или точностью
И потом мы имеем:
Использование внутреннего представления, которое больше, чем
float32
илиfloat64
, может привести к различиям в вычислительные результаты, когда разработчик делает, по-видимому, несвязанные модификации своего кода, результат который может быть таким, что значение выводится из внутреннего представления (например, в регистре) в местоположение на стек.
Теперь, в соответствии с спецификацией языка С#:
Оценка констант во время компиляции использует те же правила, что и оценка времени выполнения неконстантных выражений во время выполнения, за исключением того, что когда оценка времени выполнения выдала исключение, оценка времени компиляции вызывает ошибку времени компиляции происходят.
Но, как мы видим выше, правила на самом деле позволяют использовать более точную точность, и когда эта расширенная точность используется, на самом деле не находится под нашим прямым контролем.
И, очевидно, в разных обстоятельствах результаты могли быть точно противоположны тому, что вы наблюдали, - компилятор, возможно, снизился до более низкой точности, а время выполнения могло поддерживать более высокую точность.