КИТА unofficial
Май 06, 2024, 12:33:36 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.

Войти
Новости:
 
   Начало   ПРАВИЛА Помощь WIKI PDA Войти Регистрация  


Страниц: [1] 2  Все   Вниз
  Печать  
Автор Тема: Инверсия в С/С++  (Прочитано 44801 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Archangel
Профессор
****

Карма: +17/-2
Offline Offline

Пол: Мужской
Сообщений: 999



« : Ноябрь 18, 2007, 05:05:57 »

а=~a;
почему-то получаю: а было 255, а после операции стало -256 Непонимающий. Так и должно быть или как? Я вообще ожидал получить 0.
« Последнее редактирование: Июль 28, 2008, 06:40:55 от artem90 » Записан

Птицей Гермеса меня называют. Крылья свои пожирая, сам я себя укрощаю.
Storm
Верховный
Администратор
Аспирант
*****

Карма: +29/-0
Offline Offline

Пол: Мужской
Сообщений: 484



« Ответ #1 : Ноябрь 18, 2007, 05:24:20 »

тип у a какой?

a= !a; будет 0 только это логическая инверсия.
Записан

Только две вещи бесконечны: вселенная и тупость, и я еще не уверен по поводу вселенной. (Альберт Эйнштейн)
----------------------------------------------------
"There are two major products that came out of Berkeley: LSD and UNIX. We don't believe this to be a coincidence." (с) Jeremy S. Anderson

Проходит ирландец мимо паба....
LazarusLong
Ирландский доброволец
Проректор
*****

Карма: +181/-7
Offline Offline

Пол: Мужской
Награды:
А может я тоже хочу себе награду?
Сообщений: 6133


Ukrainian by birth, Irish by the grace of God


WWW
« Ответ #2 : Ноябрь 18, 2007, 05:31:31 »

Вот вот)) Зависит от типа.
Записан

Когда ему нужно - он русский, когда нужно - украинец, а когда ему ни хрена не нужно - он ирландец.

"...Он любил говорить факин щит
Когда что-то не так ему
Принимал он свой самый ирландский вид
И кидался трубкой в жену..."
Archangel
Профессор
****

Карма: +17/-2
Offline Offline

Пол: Мужской
Сообщений: 999



« Ответ #3 : Ноябрь 18, 2007, 05:34:34 »

Цитировать
Давайте теперь смотреть, что эти операторы делают. Начнем мы с оператора битового дополнения - ~. Просто потому, что это - единственный из битовых унарынй оператор, то есть, он работает с одним числом, а не с двумя. В принципе, его название говорит само за себя - он просто инвертирует все биты своего операнда. То есть (в предположении, что в нашем целом числе только 4 бита), проинвертировав беззнаковое число 9, мы получим 6:
9 = 1001
~9 = 0110 = 6
Загуглил нашел такое объяснение действию ~. Вот такое действие мне и нужно, но почему то
printf("%d",~9);
Выводит -10, а не ожидаемые 6.
Тип int.
Записан

Птицей Гермеса меня называют. Крылья свои пожирая, сам я себя укрощаю.
LazarusLong
Ирландский доброволец
Проректор
*****

Карма: +181/-7
Offline Offline

Пол: Мужской
Награды:
А может я тоже хочу себе награду?
Сообщений: 6133


Ukrainian by birth, Irish by the grace of God


WWW
« Ответ #4 : Ноябрь 18, 2007, 06:14:44 »

Это потому, что при инверсии инвертируются все разряды, в том числе и знаковый. Смотрите:

9, это ведь не 1001, как вам бы хотлеось. Это, на самом деле 0 000 0000 0000 1001, где первый бит - знаковый разряд.

После инверсии мы получаем - 1 111 1111 1111 0110, что сильно напоминает представление числа -10 в дополнительном коде.

10 - 1010 - 0 000 0000 0000 1010 инвертируем - 1 111 1111 1111 0101. Это у нас обратный код. Добавляем единицу, что бы получить дополнительный - 1 111 1111 1111 0110. Вуаля!. Так что всё работает верно ))).

Честно сказать, я теорию уже подзабыл, давненько не возился с обратным и дополнитлеьным кодом, но мне сдается, что объяснение в этом.
Записан

Когда ему нужно - он русский, когда нужно - украинец, а когда ему ни хрена не нужно - он ирландец.

"...Он любил говорить факин щит
Когда что-то не так ему
Принимал он свой самый ирландский вид
И кидался трубкой в жену..."
Archangel
Профессор
****

Карма: +17/-2
Offline Offline

Пол: Мужской
Сообщений: 999



« Ответ #5 : Ноябрь 18, 2007, 06:18:47 »

Ну а если мне надо все таки получить 6, что делать?
Записан

Птицей Гермеса меня называют. Крылья свои пожирая, сам я себя укрощаю.
Storm
Верховный
Администратор
Аспирант
*****

Карма: +29/-0
Offline Offline

Пол: Мужской
Сообщений: 484



« Ответ #6 : Ноябрь 18, 2007, 06:21:38 »

sizeof(a) чему равен?

Улыбка))))
на 32разрядном компьютере Улыбка)))))))
:lol:

# /etc/rc.d/rc.brain start

int - знаковое целое 32 бита

31 разряд отдан под знак, обрабатывается отдельно от остальных

int a=255;
// a == 0b 0000 0000  0000 0000  0000 0000 1111 1111
a=~a;
// a== 0b 1111 1111  1111 1111  1111 1111  0000 0000 == -256

компьютер работает правильно Подмигивающий

для того чтобы был ноль надо
Код:
  unsigned char a;

  a=255;


  printf("size %d   %d == ~%d",sizeof(a),a,(unsigned char)~a);
Записан

Только две вещи бесконечны: вселенная и тупость, и я еще не уверен по поводу вселенной. (Альберт Эйнштейн)
----------------------------------------------------
"There are two major products that came out of Berkeley: LSD and UNIX. We don't believe this to be a coincidence." (с) Jeremy S. Anderson

Проходит ирландец мимо паба....
Archangel
Профессор
****

Карма: +17/-2
Offline Offline

Пол: Мужской
Сообщений: 999



« Ответ #7 : Ноябрь 18, 2007, 06:45:56 »

Это конечно хорошо, а если у меня а расчитывается в цикле, то что надо будет расчитывать в int, а потом переводить в unsigned char? А попроще никак число не проинвертировать?
Записан

Птицей Гермеса меня называют. Крылья свои пожирая, сам я себя укрощаю.
Archangel
Профессор
****

Карма: +17/-2
Offline Offline

Пол: Мужской
Сообщений: 999



« Ответ #8 : Ноябрь 18, 2007, 07:13:07 »

Мне вообще не для printf это все надо, а для outb. То я просто смотрел что получится.
Записан

Птицей Гермеса меня называют. Крылья свои пожирая, сам я себя укрощаю.
Storm
Верховный
Администратор
Аспирант
*****

Карма: +29/-0
Offline Offline

Пол: Мужской
Сообщений: 484



« Ответ #9 : Ноябрь 18, 2007, 09:32:43 »

Операция ~ определена только для типа int, outb работает с младшими 8 битами, не нравиться приведение к типу unsigned char - убирай маской  ненужные биты в ноль. Всегда есть другой способ

Код:
  unsigned short int a;

  a=255;


  printf("size %d   %d == ~%d",sizeof(a),a,(unsigned short int)~a&0xff);



Записан

Только две вещи бесконечны: вселенная и тупость, и я еще не уверен по поводу вселенной. (Альберт Эйнштейн)
----------------------------------------------------
"There are two major products that came out of Berkeley: LSD and UNIX. We don't believe this to be a coincidence." (с) Jeremy S. Anderson

Проходит ирландец мимо паба....
Archangel
Профессор
****

Карма: +17/-2
Offline Offline

Пол: Мужской
Сообщений: 999



« Ответ #10 : Ноябрь 18, 2007, 09:44:14 »

Спасибо, но думаю сработает вариант:
не а = 255 - а;
Записан

Птицей Гермеса меня называют. Крылья свои пожирая, сам я себя укрощаю.
Storm
Верховный
Администратор
Аспирант
*****

Карма: +29/-0
Offline Offline

Пол: Мужской
Сообщений: 484



« Ответ #11 : Ноябрь 18, 2007, 09:51:05 »

на знаковом типе не сработает. 

битовые операции и маски, ИМХО, предсказуемее.
Записан

Только две вещи бесконечны: вселенная и тупость, и я еще не уверен по поводу вселенной. (Альберт Эйнштейн)
----------------------------------------------------
"There are two major products that came out of Berkeley: LSD and UNIX. We don't believe this to be a coincidence." (с) Jeremy S. Anderson

Проходит ирландец мимо паба....
Archangel
Профессор
****

Карма: +17/-2
Offline Offline

Пол: Мужской
Сообщений: 999



« Ответ #12 : Ноябрь 18, 2007, 10:08:07 »

Мне собственно и надо было избавиться от инверсии знакового бита.
Записан

Птицей Гермеса меня называют. Крылья свои пожирая, сам я себя укрощаю.
Артем
sprata
Mодератор
Завкаф
*****

Карма: +40/-5
Offline Offline

Пол: Мужской
Сообщений: 1107


« Ответ #13 : Март 24, 2008, 05:49:22 »

Это потому, что при инверсии инвертируются все разряды, в том числе и знаковый. Смотрите:
9, это ведь не 1001, как вам бы хотлеось. Это, на самом деле 0 000 0000 0000 1001, где первый бит - знаковый разряд.
После инверсии мы получаем - 1 111 1111 1111 0110, что сильно напоминает представление числа -10 в дополнительном коде.
10 - 1010 - 0 000 0000 0000 1010 инвертируем - 1 111 1111 1111 0101. Это у нас обратный код. Добавляем единицу, что бы получить дополнительный - 1 111 1111 1111 0110. Вуаля!.
Так что всё работает верно ))). Честно сказать, я теорию уже подзабыл, давненько не возился с обратным и дополнитлеьным кодом, но мне сдается, что объяснение в этом.

Я вот тоже столкнулся с такой же проблемой, что при побитовой инверсии, ручной просчет и результат который выдает Си значительно расходяться. Почитал эту тему, поискал в инете, но там все "кусками", и не очень понятен сам алгоритм перевода в дополнительный код и обратный, и для чего вообще они используються. 

LazarusLong, не могли бы Вы объяснить сам алгоритм по шагам, как надо считать, ЧТОБЫ РЕЗУЛЬТАТ ИНВЕРТИРОВАНИЯ СОШЕЛСЯ С ТЕМ ЧТО МНЕ ВЫДАЕТ СИ. Вот то что я вроде понял, если что подправтье пожалуйста:

Например, поинвертируем все то же число 9: при  ручном просчете, как уже было сказано, получаеться:
                                                                                                                                                        9 = 1001
                                                                                                                                                      ~9 = 0110 = 6
А теперь, просичтаем так, как считает Си, который выдает что  ~9 = -10, при использовании типа int :

1) Так как используетьс тип int, который занимает 2 байта, то есть 16 бит, то переводим число в 2-ичную систему и дополняем его нулями до 16 знаков, где первый бит знаковый разряд ( 0 -положительный, 1  -отрицательный):

                                                   9 (в 10-тичной)   =   0 000 0000 0000 1001  (в 2-ичной)

2) Далее инвертируем все биты числа:    получаеться   -    1 111 1111 1111 0110.  Это мы получили дополнительный код.
Если перевести это число в 10-тичную систему, то получаеться 65526, такой результат даже выдает Си, но только в том случае если вместо int поставить unsigned int.

Вот здесь возникает 1-ый вопрос по самому алгоритму: что делать дальше ? Получили дополнительный код, а вот как узнать каком числу соответствует этот дополнительный код Непонимающий

3) Не знаю правильно ли, но мне кажеться, что нужно перевести этот дополнительный код в обратный? Для этого мы должны отнять единицу от дополнительного кода Непонимающий Если это действительно так, то получаеться:

                                                 1 111 1111 1111 0110   -   1  =   1 111 1111 1111 0101.

4) Вот здесь возникает 2-ой вопрос: по сути дела, нам осталось только проинтвертировать еще раз, чтобы получить обратный код, верно Непонимающий Если, да то получааеться:
 
                                             ~ ( 1 111 1111 1111 0101 )      =     0 000 0000 0000 1010                                     

5) И наконец 3-ий вопрос: если первести это число   0 000 0000 0000 1010    в 10-тичную систему, то получим 10, а куда девалсся минус, он ведь. если верить Си должен присустствовать Непонимающий 

LazarusLong, если у Вас найдеться время ответить, или может у кого-нибудь другого, то буду очень благодарен !
                                                     
Записан
vimmax
Mодератор
Декан
*****

Карма: +42/-3
Offline Offline

Пол: Мужской
Награды:
лучшая гитара мира
Сообщений: 1713


♪♪ ♫ ♪♪ ♫ ♪♪ ♫ ♪♪


« Ответ #14 : Март 24, 2008, 06:14:51 »

все зависит от типа числа.
если у тебя int, то при инверсии получишь (-10)
если у тебя unsigned int, то при инверсии получишь (4294967286)
а в hex все равно будет (fffffff6)
Записан

♪♪ ♫  LET FOREVER BE  ♫ ♪♪ ♫ ♪♪ ♪♪ ♫
Артем
sprata
Mодератор
Завкаф
*****

Карма: +40/-5
Offline Offline

Пол: Мужской
Сообщений: 1107


« Ответ #15 : Март 24, 2008, 06:25:44 »


все зависит от типа числа.
если у тебя int, то при инверсии получишь (-10)
если у тебя unsigned int, то при инверсии получишь (4294967286)
а в hex все равно будет (fffffff6)

vimmax, спасибо за ответ !  А как на счет правильности алгоритма ручного просчета, я правильно все сделал? Почему у меня тогда куда-то пропал минус ?
Записан
Archangel
Профессор
****

Карма: +17/-2
Offline Offline

Пол: Мужской
Сообщений: 999



« Ответ #16 : Март 24, 2008, 07:18:14 »

artem90, вообще не понял что ты хочешь, дополнительный код к положительному числу получается путем дописывания в старший знаковый разряд 0, и все ничего не инвертируется дальше. А подробнее почитай в википедии там очень понятно написано.
Записан

Птицей Гермеса меня называют. Крылья свои пожирая, сам я себя укрощаю.
Артем
sprata
Mодератор
Завкаф
*****

Карма: +40/-5
Offline Offline

Пол: Мужской
Сообщений: 1107


« Ответ #17 : Март 24, 2008, 07:21:12 »

artem90, вообще не понял что ты хочешь.

Я хочу понять, как Си считает так, что получаеться -10. Как мне получить это же значение ВРУЧНУЮ Непонимающий Вот что я хотел. 

А на счет дополнительного кода, я просто в посте у Lazarusa увидел, поэтому и написал его здесь. Но я так и не понял зачем он здесь нужен.

В википедии я читал, но ведь там идет перевод чисел вне зависимости от типа данных. А в Си как раз от этого товсе и зависит, вот я и хочу понять, как?
Записан
vimmax
Mодератор
Декан
*****

Карма: +42/-3
Offline Offline

Пол: Мужской
Награды:
лучшая гитара мира
Сообщений: 1713


♪♪ ♫ ♪♪ ♫ ♪♪ ♫ ♪♪


« Ответ #18 : Март 24, 2008, 07:26:42 »

artem90 в хексах (в памяти) запись одна и та же. Только:
- если ты объявил переменную как знаковую - компилятор это помнит и переводит fffffff6 в (-10). С учетом первого разряда знакового и доп кода.

- если ты объявил переменную как беззнаковую - компилятор это помнит и переводит fffffff6 в (4294967286). Как просто целое число, без знаковогго разряда.

Часть работы делает компилятор, наверное ты это упустил ?
Записан

♪♪ ♫  LET FOREVER BE  ♫ ♪♪ ♫ ♪♪ ♪♪ ♫
Артем
sprata
Mодератор
Завкаф
*****

Карма: +40/-5
Offline Offline

Пол: Мужской
Сообщений: 1107


« Ответ #19 : Март 24, 2008, 07:30:57 »

vimmax, меня больше интересует как проинвертировать ~9 вручную, чтобы получилось -10. В своем посте я писал алгоритм, которым делал ручной просчет, но получилось не то что выдает Си. В чем же там ошибка, Вы не могли бы сказать ? И как же тогда получить ВРУЧНУЮ ~9 = -10 Непонимающий
Записан
Страниц: [1] 2  Все   Вверх
  Печать  
 
Перейти в:  

Penguins Counter Powered by MySQL Powered by PHP Powered by SMF 1.1.8 | SMF © 2006-2008, Simple Machines LLC Valid XHTML 1.0! Valid CSS! Internetmap
Страница сгенерирована за 0.067 секунд. Запросов: 30.