LINUX.ORG.RU

История изменений

Исправление wandrien, (текущая версия) :

а не max(N,M)*4

Про это подробнее расскажу, поясню, что я там имел в виду.

В компах знаковые числа представлены в «дополнительном коде». А дополняются они до соответствующей степени двойки.

То есть: Почему 32-битное число -2 записывается как 0xFFFF_FFFE. Потому что 0x1_0000_0000 - 0xFFFF_FFFE = -2. Вот такая логика формирования чисел.

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

И если переполнения нет, то старшие N нас не парят, на них можно забить. А вот если нас интересует переполнение, то забить не получится.

Почему такое умножение знаковых чисел «в лоб» работает, можно увидеть на примере, если взять десятичный аналог.

Пусть у нас будет дополнение до 1000. Запишем в дополнительном коде число -15. 1000 - 15 = 985. То есть 985 означает «-15».

Теперь умножим 17 на «-15»:

17 * 985 = 16745

Из числа 16745 отбрасываем старшие разряды, получаем 745. Это число в дополнительном коде. Переводим его в привычную форму:

-(1000 - 745) = -255

Это и есть правильный ответ: «17 * -15 = -255», всё сошлось.

Исправление wandrien, :

а не max(N,M)*4

Про это подробнее расскажу, поясню, что я там имел в виду.

В компах знаковые числа представлены в «дополнительном коде». А дополняются они до соответствующей степени двойки.

То есть: Почему 32-битное число -2 записывается как 0xFFFF_FFFE. Потому что 0x1_0000_0000 - 0xFFFF_FFFE = -2. Вот такая логика формирования чисел.

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

И если переполнения нет, то старшие N нас не парят, на них можно забить. А вот если нас интересует переполнение, то забить не получится.

Почему такое умножение знаковых чисел «в лоб» работает, можно увидеть на примере, если взять десятичный аналог.

Пусть у нас будет дополнение до 1000. Запишем в дополнительном коде число -15. 1000 - 15 = 985. То есть 985 означает «-15».

Теперь умножим на 17 на «-15»:

17 * 985 = 16745

Из числа 16745 отбрасываем старшие разряды, получаем 745. Это число в дополнительном коде. Переводим его в привычную форму:

-(1000 - 745) = -255

Это и есть правильный ответ: «17 * -15 = -255», всё сошлось.

Исходная версия wandrien, :

а не max(N,M)*4

Про это подробнее расскажу, поясню, что я там имел в виду.

В компах знаковые числа представлены в «дополнительном коде». А дополняются они до соответствующей степени двойки.

То есть: Почему 32-битное число -2 записывается как 0xFFFF_FFFE. Потому что 0x1_0000_0000 - 0xFFFF_FFFE = -2. Вот такая логика формирования чисел.

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

И если переполнения нет, то старшие N нас не парят, на них можно забить. А вот если нас интересует переполнение, то забить не получится.

Почему такое умножение знаковых чисел «в лоб» работает, можно увидеть на примере, если взять десятичный аналог.

Пусть у нас будет дополнение до 1000. Запишем в дополнительном коде число 15. 1000 - 15 = 985. То есть 985 означает «-7».

Теперь умножим на 17 на «-7»:

17 * 985 = 16745

Из числа 16745 отбрасываем старшие разряды, получаем 745. Это число в дополнительном коде. Переводим его в привычную форму:

-(1000 - 745) = -255

Это и есть правильный ответ: «17 * -7 = -255», всё сошлось.