Почему исключения OverflowException могут возникать для десятичных-> байтовых преобразований, а не для uint-> байтовых? - PullRequest
2 голосов
/ 20 октября 2011

Мне интересно, может ли кто-нибудь объяснить возникновение OverflowException, которое я вижу.

Рассмотрим следующий код:

        uint fred = 32768;
        byte wilma = (byte)fred;
        decimal bamBam = fred;
        wilma = (byte)bamBam;

Я получаю исключение OverflowException только в последней строке (при приведении decimal к byte). Я не получаю его при приведении того же значения в uint к byte.

Я не могу понять, почему это так. Есть предложения?

1 Ответ

4 голосов
/ 20 октября 2011

Явное преобразование из десятичного числа в байтовое задокументировано для выброса этого исключения , когда десятичное число находится за пределами диапазона байтов (от 0 до 255).

Исключение переполнения: значение меньше, чем Byte.MinValue или больше, чем Byte.MaxValue.

И во второй строке вы должны заметить, что значение молча переносится, wilma равно 0, поэтому при таком легальном преобразовании происходит потеря данных. Если вы хотели бы видеть такое же поведение, как показано выше для преобразования целых чисел в байты, вы должны работать в проверенном контексте.

checked
{
    uint fred = 32768;
    byte wilma = (byte)fred;
}

В неконтролируемом контексте переполнения игнорируются для преобразований между целочисленными типами. Биты более высокого порядка отбрасываются. (См. Раздел 4.1.5 спецификации языка C #.)

Проверенные и непроверенные операторы и операторы используются для управления проверка переполнения для целочисленных арифметических операций и преобразования (§7.6.12). В проверенном контексте переполнение создает ошибка времени компиляции или вызывает исключение System.OverflowException. В неконтролируемом контексте переполнения игнорируются и любые старшие биты которые не вписываются в тип назначения, отбрасываются.

Что касается избежания этих проблем, используйте типы, соответствующие данным, которые вы храните. Если данные превышают диапазон byte, используйте больший тип . Преобразования между целочисленными типами и числами с плавающей запятой особенно проблематичны, поскольку диапазоны последних значений могут намного превышать диапазон целых чисел, и, конечно, потеря данных с десятичными знаками неизбежна.

Однако, если вы продолжаете работать с десятичными преобразованиями в байты, вам необходимо помнить (и сравнивать) минимальные и максимальные значения байтов.

...