Компилятор использует дополнительную точность при вычислении некоторых выражений.В спецификации языка C # пункт 9.3.7 позволяет реализации использовать большую точность в выражении с плавающей запятой, чем тип результата:
Могут выполняться операции с плавающей запятойс большей точностью, чем тип результата операции.
Обратите внимание, что значение .05f
равно 0,0500000007450580596923828125.Когда .05f * 1000.0f
вычисляется с точностью float
, результат равен 50 из-за округления.Однако, когда он вычисляется с точностью double
или выше, результатом будет 50,0000007450580596923828125.Тогда деление 100 на это с точностью double
дает 1.999999970197678056393897350062616169452667236328125.Когда это значение преобразуется в int
, результат равен 1.
В float c = a / (b * 1000.0f);
результат деления преобразуется в float
.Даже если деление вычисляется с точностью double
и выдает 1.999999970197678056393897350062616169452667236328125, это значение становится равным 2 при округлении до float
, поэтому c
устанавливается равным 2.
В int res = (int)(a / (b * 1000.0f));
, результатделение не конвертируется в float
.Если компилятор вычисляет его с точностью double
, результат равен 1.999999970197678056393897350062616169452667236328125, и выполняется преобразование, которое дает 1.