Почему int32.maxvalue + 1 переполняет long?

c# .net

3205 просмотра

5 ответа

Если вы поместите следующий код в приложение .NET 4.5:

public const long MAXIMUM_RANGE_MAGNITUDE = int.MaxValue + 1;

Генерируется ошибка компилятора: «Операция переполняется во время компиляции в проверенном режиме». Я знаю, что я мог бы поместить это в «непроверенный» блок и быть в порядке, но мой вопрос: почему ошибка появляется в первую очередь? Очевидно, что long может содержать максимальное значение типа int плюс единицу.

Обратите внимание, что использование Int32 и Int64 вместо long и int, похоже, не помогает.

Автор: BradleyDotNET Источник Размещён: 12.11.2019 09:25

Ответы (5)


17 плюса

Решение

Это потому, что вычисления в правой части присваивания выполняются в целочисленном виде. И это переполняется целое число

Вы можете исправить это с помощью:

public const long MAXIMUM_RANGE_MAGNITUDE = int.MaxValue + (long)1; // or 1L

Приведя хотя бы один из операндов к длинному

Причина возникновения ошибки указана в спецификациях C #.

См. Раздел C # Спецификация 4.1.5 (Интегральные типы)

Для двоичных операторов +, -, *, /,%, &, ^, |, ==,! =,>, <,> = И <= операнды преобразуются в тип T, где T является первым из int, uint, long и ulong, которые могут полностью представлять все возможные значения обоих операндов. Затем операция выполняется с использованием точности типа T, а тип результата - T (или bool для реляционных операторов). Не допускается, чтобы один операнд имел тип long, а другой - тип ulong с бинарными операторами.

В вашем случае, поскольку оба операнда сложения могут быть представлены в, intследовательно, вычисление выполняется в целочисленном виде. Явное приведение одного из операндов longприведет к longрезультату и, следовательно, к ошибке переполнения.

Автор: Habib Размещён: 31.01.2014 07:44

4 плюса

Ваш код на самом деле выглядит так:

(long)(int.MaxValue + 1)

Но так как .Net Framework имеет встроенное неявное преобразование между int и long, вам не нужно явно ставить бросок на long в вашем коде.

Итак, во-первых, эта часть кода выполняется:

int.MaxValue + 1

и результатом этой операции является intзначение, которое вызывает и переполнение исключения. Таким образом, ваш код даже не имеет возможности начать преобразование из int в long.

Автор: Paweł Bejger Размещён: 31.01.2014 07:44

1 плюс

Я думаю, что это связано со значением int.MaxValue + 1, вычисляемым до того, как произойдет приведение к long. Конечно, long может содержать значение, но поскольку вы выполняете сложение целых чисел, невозможно сохранить целочисленное значение int.MaxValue + 1в int до тех пор, пока не будет произведено приведение.

Автор: Justin C Размещён: 31.01.2014 07:44

1 плюс

пытаться

public const long MAXIMUM_RANGE_MAGNITUDE = (long)int.MaxValue + 1L;
Автор: RadioSpace Размещён: 31.01.2014 07:44

1 плюс

Приведите постоянное значение к длинному.

public const long MAXIMUM_RANGE_MAGNITUDE = (long) int.MaxValue + 1;
Автор: Scott Corbett Размещён: 31.01.2014 07:47
32x32