8 / 37 · Теория
Дополнительный код, расширение знака и переполнение
Различайте знаковую интерпретацию битовой строки и условия переполнения сложения с помощью формул и контрпримеров.
Уроки доступны бесплатно. Запишитесь, чтобы сохранять прогресс.
Вес старшего бита меняется
-битное целое в дополнительном кодеДополнительный код представляет знаковые целые битовой последовательностью фиксированной ширины. Для n бит диапазон составляет от −2^(n−1) до 2^(n−1)−1. интерпретируется так:
Четырёхбитное 1010 означает 10 как unsignedБеззнаковая интерпретация (unsigned) рассматривает битовую последовательность как неотрицательное целое. Диапазон n бит — от 0 до 2^n−1; знаковая интерпретация тех же битов может дать другое число. Подробнее и −6 как signed. Это не схема «отделить знаковый бит, оставшееся прочитать как модуль». При фиксированной ширине получают инверсией битовИнверсия — операция NOT, меняющая 0 на 1 и 1 на 0. Черта над формулой означает применение NOT ко всему выражению под ней. Подробнее и добавлением 1, но положительное +8 для минимального −8 не входит в тот же 4-битный signed-диапазон.
Расширение должно сохранять значение
Unsigned расширяют нулями слева, signed — копиями исходного знакового бита. Превращение 1010 в 00001010 даёт +10, в 11111010 — −6. Даже расширение одинаковых битов требует разных схем при разной интерпретации.
logic signed [3:0] a, b;
logic signed [4:0] exact;
logic [3:0] result;
logic overflow;
assign exact = {a[3], a} + {b[3], b};
assign result = exact[3:0];
assign overflow = (a[3] == b[3]) && (result[3] != a[3]);В примере складываются два знаковых операнда без carry на входе. В exact сохраняется 5-битная сумма, затем проверяется правильность знака суженного результата.
Начальное значение — 11111010. Убедитесь, что unsigned 250 и signed −6 представлены одними битами. Изменение b7 меняет значения двух интерпретаций в разных направлениях.
11111010 → unsigned 250 · signed -6 · hex 0xFA
Carry и знаковое переполнение различаются
Если при сложении чисел одного знака знак результата изменился, произошло переполнение. В 4 битах сохраняется как 1010, выглядя как −6, а — как 0111, выглядя как +7. При сложении двух чисел разных знаков такого выхода за диапазон не возникает.
Смешение signed и unsigned в RTL усложняет правила сравнения и расширения. Явно задавайте ширину и знаковость обоих операндов, включайте в граничные тесты минимум, −1, 0 и максимум.
Попробуйте сами
Для 4-битных signed найдите сохранённые биты и overflow в и . Объясните также результат отрицания .
Прочитать объяснение
представляется как 1001, переполнения нет. 10 выходит за диапазон и сохраняется как 1010 (−6), поэтому overflow есть. Инверсия −8 с добавлением 1 снова оставляет 1000: +8 в этом диапазоне не представимо. Нельзя использовать это как корректное вычисление модуля числа.