В нашем коде есть двойник, который нам нужно преобразовать в 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