Почему 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 шт):

Автор решения: rotabor

Вещественные числа в процессоре представляются в экспоненциальном формате, поэтому 2147483647 представляется как 1,111111111111111111111111111111 * 2^30. Тип float может содержать только 24 разряда, поэтому лишние разряды справа отбрасываются с округлением. По правила округления получается 1 * 2^31. Дальше всё следует из этого.

В double 1,111111111111111111111111111111 * 2^30 влезает без округления.

Третий фрагмент выглядит интересно. Получается такая особенность преоразования, когда (int) тупо представляет битовое значение как int.

→ Ссылка