В нашем коде есть двойник, который нам нужно преобразовать в int.
double score = 8.6;
int i1 = Convert.ToInt32(score);
int i2 = (int)score;
Кто-нибудь может объяснить мне, почему i1 != i2?
В результате я получаю следующее: i1 = 9и i2 = 8.
В нашем коде есть двойник, который нам нужно преобразовать в int.
double score = 8.6;
int i1 = Convert.ToInt32(score);
int i2 = (int)score;
Кто-нибудь может объяснить мне, почему i1 != i2?
В результате я получаю следующее: i1 = 9и i2 = 8.
Ответы:
Потому что Convert.ToInt32раундов:
Возвращаемое значение: округлено до ближайшего 32-разрядного целого числа со знаком. Если значение находится посередине между двумя целыми числами, возвращается четное число; то есть 4,5 преобразуется в 4, а 5,5 преобразуется в 6.
... пока приведение обрезается :
При преобразовании значения double или float в целочисленный тип значение усекается.
Обновление: см. Комментарий Джеппе Стига Нильсена ниже для дополнительных различий (которые, однако, не вступают в игру, если scoreэто действительное число, как здесь).
scoreбыли 8.5вместо 8.6. Я обновил ответ, включив цитаты. Спасибо за вклад.
scoreравно NaNили бесконечность или конечное значение, но вне диапазона Int32, то Convert.ToInt32будет выдано исключение. Cast вернет int, но вы не узнаете, какой из них (в моей реализации это Int32.MinValue), потому что вы находитесь в uncheckedконтексте. (Если вы находитесь в checkedконтексте, актерский состав также вызовет исключение в этих случаях.)
Doubleтиповое число 10000000000.6(десять миллиардов целых шесть десятых) - это «реальное» число. Использование приведения к intэтому даст странный результат (если вы не находитесь в checkedконтексте, но, вероятно, это не так).
Приведение игнорирует все, что находится после десятичной точки, поэтому 8,6 становится 8.
Convert.ToInt32(8.6) - это безопасный способ обеспечить округление двойного числа до ближайшего целого числа, в данном случае 9.
В приведенном примере ваше десятичное число - 8,6 . Если бы это было 8.5 или 9.5, утверждение i1 == i2 могло бы быть правдой. Фактически, это было бы верно для 8,5 и ложно для 9,5.
Пояснение:
Независимо от десятичной части, второй оператор int i2 = (int)scoreотбросит десятичную часть и просто вернет вам целую часть. Это довольно опасная вещь, так как может произойти потеря данных.
Теперь для первого утверждения могут произойти две вещи. Если десятичная часть равна 5, то есть наполовину, необходимо принять решение. Мы округляем в большую или меньшую сторону? В C # класс Convert реализует банковское округление. См. Этот ответ для более глубокого объяснения. Проще говоря, если число четное, округлить в меньшую сторону, если число нечетное - округлить в большую сторону.
Например, рассмотрите:
double score = 8.5;
int i1 = Convert.ToInt32(score); // 8
int i2 = (int)score; // 8
score += 1;
i1 = Convert.ToInt32(score); // 10
i2 = (int)score; // 9
ToInt32 раундов. Приведение к int просто отбрасывает нецелочисленный компонент.
Math.Truncate(score)более явно выраженное намерение, чем(int)score