Underflow и Overflow в бинарном сложении - PullRequest
0 голосов
/ 07 февраля 2019

В случае:

0b10001111+0b10011000 = 0b100100111 

Является ли случай недостаточного заполнения?как два члена отрицательны, а результат положителен?

Когда мы получим переполнение?как 9-й бит будет всегда 1?когда оба восьмых бита равны 1

1 Ответ

0 голосов
/ 07 февраля 2019

0b1000 1111 + 0b1001 1000 = 0b1 0010 0111

Включая перенос как n + 1-й бит результата в бессмысленно для дополнения 2 с.То, что вы можете сделать, это либо придерживаться оригинального размера

0b1000 1111 + 0b1001 1000 = 0b0010 0111 // неверный

, либо расширить операнды до n + 1 бит иполучить результат n + 1 бит.

0b1 1000 1111 + 0b1 1001 1000 = 0b1 0010 0111 // действительный

Причина в том, что дополнение 2s работает путем добавления 2^ n к отрицательным целым числам, чтобы сделать их положительными.(для кодирования a <0 = - | a | используйте 2 ^ n + a или 2 ^ n - | a |, то есть дополнение к 2 ^ n из | a |, отсюда и название дополнения 2s). </p>

Это здорово, так как закодированное значение равно (2 ^ n) + a, если a <0, или a, если a≥0, и если вы игнорируете 2 ^ n, вы можете добавить целое число со знаком, не беспокоясь о знакеоперанды.Но вы <em>должны игнорировать выполнение (за исключением того, что касается действительности).

Чтобы получить точные правила действительности, вы должны рассмотреть различные ситуации:

1 / A, B> = 0

enter image description here

Результат действителен, если MSB = 0 ⇒ c_n-1 = 0 (и мы всегда имеем c_n = 0)

2 / A, B <0 </p>

enter image description here

Результат действителен, если MSB = 1 ⇒ c_n-1 = 1 (и мы всегда имеемc_n = 1)

3 / A> = 0, B <0 </p>

enter image description here

Результат не может быть слишком положительным или слишком отрицательным ивсегда в силе.И у нас всегда есть c_n = c_n-1

. Мы видим, что глобальное правило, которое указывает, является ли результат действительным, состоит в том, что c_n == c_n-1 (или c_n ⊕ c_n-1 указывает на переполнение).

Есть много других эквивалентных правил.Например:
результат действителен, если (знак (A)! = Знак (B)) или ((знак (A) == знак (B)) и (знак (A) == знак (A + B))
, которое можно выразить в C как
((a^b) | (a^~(a+b)))&(1<< sizeof (int) -1)

...