Целочисленное дополнение со знаком, требуется уточнение - PullRequest
1 голос
/ 19 июня 2011

У меня есть следующие целые числа со знаком:

(4bits)a = 6;
(4bits)b = 7;
(4bits)c;
c = a + b;

Будет ли с = 13 или с = -3? Если я делаю двоичную математику и предполагаю, что это 4-битное число: 0110 + 0111 = 1101 (-8 + 4 + 0 + 1) = -3

Ответы [ 5 ]

10 голосов
/ 19 июня 2011

Вопреки распространенному мнению, C имеет 4-битные целочисленные типы. Однако он не имеет объектов этих типов, только битовые поля (6.7.2.1/9, «Битовое поле интерпретируется как целочисленный тип со знаком или без знака, состоящий из указанного количества битов»). «):

#include <stdio.h>

typedef struct int4bit {
    signed int value:4;
} int4bit;

int main() {
    int4bit a, b, c;
    a.value = 6;
    b.value = 7;
    c.value = a.value + b.value;
    printf("%d\n", c.value);
}

Вывод этой программы с моим компилятором -3, , однако это не гарантируется стандартом. Причина в том, что выражение a.value + b.value имеет тип int (из-за правил целочисленного продвижения, 6.3.1.1/2) и значение 13. Значение 13 не может быть представлено в 4-битном целом со знаком, и, следовательно, одно из двух происходят вещи: либо результат, определенный реализацией, либо сигнал, определяемый реализацией (6.3.1.3/3).

Короче говоря, все, что вы можете сделать, это проверить документацию вашего компилятора или запустить код и посмотреть, что он делает. Но этот результат, -3, вполне естественен для реализации с представлением дополнения 2s целочисленных типов со знаком.

Значение не может быть 13, потому что 13 не находится в диапазоне значений, представляемых 4-битным целым числом со знаком. Все разрешено, если реализация документирует это, например, это может быть -2, на машине дополнения 1 с без проверки переполнения. Не то чтобы вы, вероятно, когда-либо сталкивались с такой машиной ...

Это особый случай, потому что единственный способ получить 4-битный целочисленный тип - это битовое поле. В общем случае переполнение целочисленной арифметики со знаком является неопределенным поведением (6.5 / 5, «результат находится ... вне диапазона представимых значений для его типа»). В вашем примере нет арифметического переполнения из-за повышения до int, поэтому диапазон поведения, доступный для реализации, ограничен - нельзя форматировать жесткий диск. Но если вы переполните int, то вы полностью зависите от своего компилятора.

5 голосов
/ 19 июня 2011

Если целые числа в системе, которую вы используете, имеют длину 4 бита, то результат действительно будет переполнен, и результат будет -3. Тем не менее, C-целые по крайней мере 16-битные и поэтому результат будет 13.

1 голос
/ 19 июня 2011

Результат операции зависит от поведения.C не требует, чтобы архитектура использовала представление дополнения до двух (даже если это делают почти все).

Но вы должны переписать ваш пример большими числами, так как люди здесь путаются с вашим «давайте притворимся, что int - 4bit"вещь.

0 голосов
/ 19 июня 2011

Вы пробовали это в компиляторе? В сети есть один бесплатный ...

http://codepad.org/MHUee7hx

#include "stdio.h"

int main(int argc, char* argv)
{
  int a = 6;
  int b = 7;
  int c;
  c = a + b;
  printf("%i\n", c);
  return 0;
}

13

Кроме того, в C. нет 4-битного int. Если у вас 4-битное int, вы не используете стандартную версию C.

См. Этот вопрос - В чем разница между int и long в C ++?

В частности, ответ Мартина.

0 голосов
/ 19 июня 2011

Это 13. int s в C гарантированно будет по крайней мере 16 бит.

...