Я получаю 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);