$ echo $(( 255 ))
255
$ echo $(( 33 ))
33
$ echo $(( ~33 ))
-34
$ echo $(( ~255 ))
-256
$
и мое ядро:
$ uname -a
Linux HOSTNAME 3.2.0-40-generic-pae #64-Ubuntu SMP Mon Mar 25 21:44:41 UTC 2013 i686 i686 i386 GNU/Linux
ВОПРОС: ~
для отрицания числа AFAIK. Но почему ~33
производит -34
и почему ~255
производит -256
?
bash
shell
arithmetic
Гаско Питер
источник
источник
Ответы:
Страница руководства bash гласит:
Числа со знаком обычно хранятся в дополнительном представлении Two :
Это означает, что если вы возьмете число, подобное 2, оно будет поразрядно интерпретировано как 0010. После побитового отрицания это становится 1101, что является представлением -3.
источник
Это результат дополнения арифметики двух.
~
это побитовое отрицание, которое инвертирует все биты, с которыми работают. Арифметика дополнения двух работает, инвертируя все биты и добавляя 1. Поскольку вы только перевернули биты, но не добавили один, вы получите то же самое число, инвертированное, минус один.В Википедии есть хорошая статья о двух дополнениях здесь .
В качестве примера:
0011
1101
0011
дает вам1100
, что -4, так как вы не добавили 1.источник
Оператор ~ является побитовым оператором NOT. Использование это не то же самое, что отрицание числа.
Из википедии побитовая операция NOT равна получению дополнения до значения минус один:
Отрицание двоичного числа эквивалентно принятию его значения из двух дополнений.
Использование оператора ~ NOT = принимает значение, состоящее из одного дополнения.
Проще говоря, ~ просто переворачивает все биты двоичного представления .
Для ваших примеров:
Или в десятичной арифметике, используя формулу ~ x = -x - 1:
и
источник
Проблема в том, что ~ является побитовым оператором. Следовательно, вы отрицаете больше битов, чем, возможно, намереваетесь. Вы можете увидеть это лучше, преобразовав результаты в гекс, например:
по сравнению с тем, что у вас было:
Я предполагаю, что вы хотите отрицать 0x33. Если это так, то это будет работать:
Вы также должны использовать &, который является побитовым и оператором, чтобы избежать всех ff в начале.
источник
Оператор
~
(арифметический) переворачивает все биты , он называется оператором побитового отрицания:Таким образом, в местах, где контекст является арифметическим, он меняет число со всеми битами в виде нулей на все биты в единицах. A
$(( ~0 ))
преобразует все биты числового представления (обычно в настоящее время 64 бита) во все.Число со всеми интерпретируется как отрицательное число (первый бит
1
)1
или просто-1
.То же самое происходит со всеми другими числами, например:
$(( ~1 ))
переворачивает все биты:Или в двоичном виде:
1111111111111111111111111111111111111111111111111111111111111110
Что интерпретируется как число в представлении два:
В общем, математическое уравнение человека таково, что
$(( ~n ))
равно$(( -n-1 ))
И (ваш вопрос):
источник
Сначала вы должны понять, что 33 - это 32-битное или 64-битное число.
Для удобства я беру восьмибитное число (= 1 байт)
десятичное число 33 состоит из восьми битов: 00100001, переворачивание битов приводит к 11011110.
Поскольку старший бит равен 1, это отрицательное число.
Распечатывая отрицательное число, система печатает знак минус и затем дополняет двоичное число отрицательным числом.
Второе дополнение: переворачивание битов и добавление 1.
11011110 ==> 00100001 ==> добавление 1 ==> 00100010 приводит к десятичному знаку 34 после знака минус.
источник