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

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


Страниц: 1 2 [Все]   Вниз
  Печать  
Автор Тема: Инверсия в С/С++  (Прочитано 44810 раз)
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 Непонимающий
Записан
Archangel
Профессор
****

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

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



« Ответ #20 : Март 24, 2008, 08:03:08 »

Элементарно поменять знаковый бит с 0 на 1.
0 1001 =9
1 0110 =-10
Записан

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

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

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


« Ответ #21 : Март 24, 2008, 08:14:05 »

1 0110 =-10

1 0110   =   1*2^4 + 0*2^3 + 1*2^2 + 1*2^1 + 0*2^0 = 16 + 4 +2 = 22

Archangel, не знаю как у Вас получилось, что  1 0110 = -10 ?
Записан
Archangel
Профессор
****

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

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



« Ответ #22 : Март 24, 2008, 08:18:41 »

Ну я тебе условно показал, отделенные пробелом - знаковые разряды. Ты все время пытаешься перевести числа как положительные. А если старший(знаковый) разряд 1, то число воспринимается как отрицательное. То есть старший разряд показывает будет перед числом минус или нет. Для знакового типа.
PS Прочитай еще раз пост Storm'a на прошлой странице, там же написано, что знаковый разряд обрабатывается отдельно.
Записан

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

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

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


Злой и страшный :)


« Ответ #23 : Март 24, 2008, 09:08:16 »

Пусть signed char x=9;  (чтобы 1 байт был и меньше писать Подмигивающий )

x=00001001(2)

~x=11110110(2)

А вот теперь переводим в 10-ную, не забывая, что компьютер хранит числа в дополнительном коде (далее ДК). То есть абсолютное значени отрицательного числа (т.е. у которого старший бит =1) можно всего получить, инвертируя всё, кроме знака и прибавляя 1.

~1110110(2)=0001001(2)

00001001(2)+1 = 00001010(2)=10(10) - итого, модуль числа 10.

Результат: -10



Подробнее про дополнительный код здесь: Дополнительный код
« Последнее редактирование: Март 24, 2008, 09:19:59 от EvilMax » Записан

Оптимальная концентрация кофе - это когда код уже дает советы, как его написать, но еще не спорит с тобой и не подкалывает в случае неудач...
---
Существует три способа распространения программного обеспечения: воровство, грабёж и обмен краденым. (c) Неизвестный программист
Артем
sprata
Mодератор
Завкаф
*****

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

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


« Ответ #24 : Март 24, 2008, 09:54:52 »

EvilMax, спасибо большое, что объснили !
Записан
Страниц: 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.096 секунд. Запросов: 33.