Как я могу остановить исключение OverflowException на целочисленное деление?

Я получаю OverflowException, брошенный на меня, когда я не хочу их (или так я думаю). Я выполняю некоторые нечетные вычисления, где ожидаю, что значения переполняются, отбрасывая переполненные биты. Кажется, я не могу заставить это работать правильно, хотя. В основном это одна пара я и 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);

Update:

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

О ожидаемом значении:

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

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

Ответ 1

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

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

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

Ответ 2

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

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

Ответ 3

Вы можете обойти это с помощью немного отливки в/из Int64:

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

Ответ 4

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

long x = (long)i / j;

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

int x = (int)Math.Min((long)i / j, int.MaxValue);