Добавление переменной в языке Си - PullRequest
1 голос
/ 10 апреля 2010

основной () { символ а, б, в; а = 6; б = -5; с = а + б; printf ("% d% d% d \ n", a, b, c); }

Here , what actually happens 

00000110
10000101 
--------
10000111
--------
So values c will -11 , then how come it is 1. 

Ответы [ 5 ]

6 голосов
/ 10 апреля 2010

Кажется, что вы путаете понятия дополнения и знака-бита 2, а также побитового или сложения в C.

(А кто бы мог ожидать 6 + (-5) ≠ 1…)


(1) 2-е дополнение и знак-бит

На большинстве архитектур отрицательные числа реализованы как дополнение 2 его величины. В то время как стандарт C не требует использования дополнения 2, он является самым популярным. В дополнении 2 отрицание x строится как ~x + 1, например

  5   = 0000 0101
 ~5   = 1111 1010    # ~x means 1's complement, a.k.a. bitwise-NOT
 ~5+1 = 1111 1011    # +1 means add 1 to the integer.

Это двоичное представление -5. Старший бит целого числа называется знаковым битом , поскольку он определяет знак целого числа. Все отрицательные целые числа в дополнении 2 имеют знак бита = 1. Но простое переключение знака не отменяет число. Это всего лишь показатель того, что число отрицательное или нет.


(2) Побитовое или сложение в C

+ означает целочисленное сложение в C и во всех других практических языках, потому что целочисленное сложение гораздо полезнее, чем побитовое или. Поэтому, хотя в логических доказательствах ИЛИ широко записывается как +, ни один язык программирования не распознает + для побитового ИЛИ.

В C a char - это просто целое число со знаком, длина которого ровно 1 байт. Поведение такое же, как и у всех других типов целых чисел со знаком. Вы должны использовать | для побитового ИЛИ.

  0000 0110               0000 0110
+ 1000 0101             | 1000 0101
———————————             ———————————             
  1000 1011               1000 0111
       ^^--- note the carry ---^^
6 голосов
/ 10 апреля 2010

Ваша ошибка: -5 в дополнении до двух не 10000101. В 32-битном это: 11111111111111111111111111111011

6, это:

00000000000000000000000000000110

Сумма:

  11111111111111111111111111111011
+ 00000000000000000000000000000110
  --------------------------------
  00000000000000000000000000000001

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

2 голосов
/ 10 апреля 2010

Вы, похоже, немного озадачены тем, как отрицательные значения хранятся на компьютере. То, что у вас там, называется «знак и величина». Поскольку арифметика сложна с числами знаков и величин (как вы уже видели!), В основном все компьютеры используют «дополнение двух». Это легко рассчитать, выполнив два шага:

  1. Отразить все биты (то есть взять дополнение)
  2. Добавить один

При этом 0000101 становится 1111011 (для простоты в 8 битах). Тогда сложение легко:

  1111011 = -5
+ 0000110 =  6
 ________ |
  0000001 =  1

Что равно 1, как и ожидалось.

2 голосов
/ 10 апреля 2010
#include<stdio.h>
    main()
    {
            char a,b,c;
            a=6;
            b=-5;
            c=a+b;
            printf("%d %d %d \n", a,b,c);
    }

    /*
     *
     *  Here 6 value as = 00000110
     *       -5 value will be treated as complement of 5.
     *
     *       Actual 5 value is 00000101
     *       Complement of 5 is 11111010
     *        Then we need to add 1 to the complement of 5
     *        So that time value is 11111011
     *
     *        Now we need to add 5 and 6
     *
     *        00000110
     *        11111011
              ---------
              00000001
    */ 
1 голос
/ 01 августа 2013

По вашему примеру:

Символ 1 байта означает 8 бит (bbbb bbbb)

Двоичный из 6

0000 0110

Двоичный из 5 - это

0000 0101

За -5 мы возьмем 2 комплимента из 5, поэтому 2 комплимента из 5 будут

1111 1011

Двоичное добавление:

0000 0101
1111 1011
---------
0000 0001
---------

0000 0001 Which is equal to 1 hence proved :)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...