Почему int.MaxValue сконвертированное в float?, нельзя сконвертировать обратно?
такой код работает "как ожидается"
double? x = null;
var y = x ?? int.MaxValue;
Console.WriteLine(y);
int z = Convert.ToInt32(y);
Console.WriteLine(z);
2147483647
2147483647
такой код падает с OverflowException
float? x = null;
var y = x ?? int.MaxValue;
Console.WriteLine(y);
int z = Convert.ToInt32(y);
Console.WriteLine(z);
2.1474836E+09
Unhandled exception. System.OverflowException: Value was either too large or too small for an Int32.
а такой код ведёт себя ещё неадекватнее
float? x = null;
var y = x ?? int.MaxValue;
Console.WriteLine(y);
int z = (int)y;
Console.WriteLine(z);
2.1474836E+09
-2147483648
Почему так?
Ответы (1 шт):
Вещественные числа в процессоре представляются в экспоненциальном формате, поэтому 2147483647 представляется как 1,111111111111111111111111111111 * 2^30. Тип float может содержать только 24 разряда, поэтому лишние разряды справа отбрасываются с округлением. По правила округления получается 1 * 2^31. Дальше всё следует из этого.
В double 1,111111111111111111111111111111 * 2^30 влезает без округления.
Третий фрагмент выглядит интересно. Получается такая особенность преоразования, когда (int)
тупо представляет битовое значение как int.