Почему Int32.MaxValue * Int32.MaxValue == 1? - PullRequest
5 голосов
/ 09 июня 2010

Я знаю, Int32.MaxValue * Int32.MaxValue даст число больше Int32; Но не должно ли это утверждение вызвать какое-то исключение?

Я столкнулся с этим, когда делал что-то вроде IF (X * Y > Z), где все Int32. X и Y достаточно велики, вы получаете фиктивное значение от X * Y.

Почему это так и как обойти это? кроме приведения все к Int64.

Ответы [ 6 ]

26 голосов
/ 09 июня 2010

Потому что int32 ограничивает результаты 32 битами.

Итак, если вы посмотрите на математику на уровне байтов.

FFFFFFFF * FFFFFFFF = FFFFFFFE00000001

Как видите, самые младшие 4 байта= 1.

19 голосов
/ 09 июня 2010

По умолчанию арифметика C # выполняется в неконтролируемом контексте, то есть значения переворачиваются.

Вы можете использовать отмеченные и непроверенные ключевые слова для управления этим поведением.

8 голосов
/ 09 июня 2010

Интересно отметить, что это работает независимо от используемой вами базы:

(n-1)*(n-1)  mod n 
n^2 - 2n + 1 mod n
0   -  0 + 1 mod n
           1 mod n
6 голосов
/ 09 июня 2010

Вы отключили проверку переполнения в вашем проекте. При включенном режиме он выдаст исключение.

6 голосов
/ 09 июня 2010

Вы должны попросить об этом:

checked {
    int a = int.MaxValue;
    int b = int.MaxValue;
    int c = a * b;    // kaboom
}
2 голосов
/ 09 июня 2010

Int32.MaxValue (с использованием значения, данного здесь ) составляет 2 147 483 647.

В базе 2 это: 111 1111 1111 1111 1111 1111 1111 1111 ... 2 ^ 31-1. Первый бит является знаковым битом.

Если вы умножите это на себя, вы получите: 11 1111 1111 1111 1111 1111 1111 1111 0000 0000 0000 0000 0000 0000 0000 0001

Возвращаясь к исходной проблеме «почему это 1?», Поскольку Integer.MaxValue является максимальным значением, которое вызывает целочисленное переполнение. Результат усекается до 31 младшего бита, который равен 0 и плюс 1.

Редактировать: Вот учебник по двоичному умножению. Используя простой случай всех 1 с: 111 * 111

вы получите: 00111 01110 + 11100 = 100001

Вы можете расширить это для случая Int32.MaxValue. Я сократил его до 3 цифр для краткости.

Также, как сказал другой ответ, в C # эти переполнения будут происходить по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...