Как остановить OverflowException при целочисленном делении?

Я получаю OverflowException, когда я не хочу их (или я так думаю). Я выполняю некоторые странные вычисления, когда ожидаю переполнения значений, отбрасывая переполненные биты. Кажется, я не могу заставить это работать должным образом все же. По сути, это одна пара i и j, которая происходит, когда я перебираю огромные множества (от int.MinValue до int.MaxValue).

// i and j are ints
// i is -2147483648
// j is -1
var x = i / j;

// I also tried using unchecked keyword, but it doesn't help    
var x = unchecked(i / j);

Обновить:

Ожидаемое математическое значение -2147483648 / -1 равно 2147483648. Однако этот определенный код на самом деле не пытается найти число. Это часть серии манипуляций, которые трудно понять. Честно говоря, я даже сам не знаю, каково было намерение, потому что я на самом деле не документировал метод, и все, что ему понадобилось, - это один день, чтобы поднять серьезные WTF-пузыри над моей головой. Все, что я знаю, это работает как задумано, с помощью специального кода, предназначенного для обработки дела

Об ожидаемой стоимости:

Поскольку int может хранить только 2147483647 на максимуме, я ожидаю сбросить выходное значение переполнения 0.

Если я вообще что-то узнал об этом, то, вероятно, важна документация для непонятных методов.

4 ответа

Решение

Я считаю, что это единственный случай, когда вы получите это исключение. Это единственное подразделение внутри Int32 диапазон, который может переполниться. (Конечно, есть деление на ноль, но это другое исключение.)

Так что если вы хотите избежать OverflowException вам нужно только разобраться с этим делом. Что вы хотите от этого? Напишите метод, который определяет этот точный случай, а в противном случае выполняет нормальное деление.

Примечание: это также то, почему вы не должны пытаться отменить сравнение, просто отрицая результат. Если вы хотите отсортировать что-то в порядке убывания, а не в порядке возрастания, то вместо использования -Compare(x, y) использование Compare(y, x), Отрицание не дает переполнения для int.MinValue (если вы не в проверенном контексте) - он просто молча возвращает int.MinValue,

Двойное дополнение означает, что целые числа будут в диапазоне от 2^32 - 1 до -2^32, поэтому -2147483648 / -1 возвращает число, которое не может быть представлено int,

Вы можете попробовать положить его в long, Там нет причин использовать var в этой ситуации.

Вы можете обойти это с небольшим приведением к / из Int64:

var x = (int)((long)i / j);

Ты делаешь это. Почему вы используете var Вот? Он теряет способность показывать вам тип арифметического результата для сохранения 1 символа...

long x = (long)i / j;

Если вы хотите насыщения, вы можете:

int x = (int)Math.Min((long)i / j, int.MaxValue);
Другие вопросы по тегам