Ответ 1
См. комментарии от @EricLippert.
НИЧЕГО разрешено изменять результат - позвольте мне подчеркнуть, что снова НИЧЕГО, ЧТО ТАКОЕ, включая фазу Луны, разрешено измените, вычисляются ли поплавки с точностью до 32 бит или выше точность. Процессор всегда разрешен по любой причине решите внезапно начать выполнять арифметику с плавающей запятой в 80 бит или 128 бит или независимо от того, что он выбирает, если он больше или равен 32-битная точность. Видеть (. 1f +.2f ==. 3f)!= (.1f +.2f).Equals(.3f) Почему?для более подробной информации.
Запрашивая, что конкретно в этом случае заставило процессор решить использовать более высокую точность в одном случае, а не в другом - это проигрыш игра. Это может быть что-либо. Если вам нужны точные вычисления в десятичные цифры, затем используйте метод aptly с именем
decimal
. Если вам требуется повторяющихся вычислений в поплавках, тогда С# имеет два механизма для заставляя процессор вернуться к 32 бит. (1) явно отбрасывается (float) без необходимости или (2) сохранить результат в элементе массива float или float поля ссылочного типа.
Поведение здесь не имеет ничего общего с типом Nullable. Это вопрос о том, что поплавки никогда не были точными и рассчитывались с разной точностью по прихотям процессора.
В общем, это сводится к совету, что, если точность важна, лучше всего использовать что-то другое, кроме float
(или использовать методы, описанные @EricLippert, чтобы заставить процессор использовать 32-битную точность).
Ответ от Эрика Липперта по связанному вопросу также полезен для понимания того, что происходит.