$ echo $(( 255 ))
255
$ echo $(( 33 ))
33
$ echo $(( ~33 ))
-34
$ echo $(( ~255 ))
-256
$
a moje jądro to:
$ 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
PYTANIE: ~
służy do zanegowania liczby AFAIK. Ale dlaczego ~33
produkuje -34
i dlaczego ~255
produkuje -256
?
bash
shell
arithmetic
Gasko Peter
źródło
źródło
Odpowiedzi:
Strona podręcznika bash mówi:
Podpisane liczby są zwykle przechowywane w reprezentacji uzupełnienia Two :
Oznacza to, że jeśli weźmiesz liczbę taką jak 2, zostanie ona zinterpretowana bitowo jako 0010. Po negacji bitowej staje się to 1101, co reprezentuje -3.
źródło
Jest to wynik arytmetyki dopełniacza dwóch.
~
jest bitową negacją, która odwraca wszystkie operowane bity. Arytmetyka komplementu dwóch działa poprzez odwrócenie wszystkich bitów i dodanie 1. Ponieważ odwróciłeś tylko bity, ale nie dodałeś jednego, otrzymujesz tę samą liczbę, odwróconą, minus jeden.Wikipedia ma dobry artykuł na temat uzupełnienia dwóch tutaj .
Jako przykład:
0011
1101
0011
daje ci wartość1100
-4, ponieważ nie dodałeś 1.źródło
Operator ~ jest bitowym operatorem NOT. Używanie go to nie to samo, co negowanie liczby.
Z wikipedii , bitowa operacja NIE jest równoznaczna z przyjmowaniem uzupełnienia dwóch wartości minus jeden:
Negowanie liczby binarnej jest równoznaczne z przyjęciem jej wartości dwóch uzupełnień.
Za pomocą operatora ~ NOT = weź wartość jednego uzupełnienia.
Mówiąc prościej ~ odwraca wszystkie bity reprezentacji binarnej .
Dla twoich przykładów:
Lub w arytmetyce dziesiętnej przy użyciu wzoru ~ x = -x - 1:
i
źródło
Problem polega na tym, że ~ jest nieco mądrym operatorem. Dlatego negujesz więcej bitów, niż ci się wydaje. Możesz to lepiej zobaczyć, konwertując wyniki na hex, np .:
w porównaniu do tego, co miałeś:
Zakładam, że masz zamiar zanegować 0x33. W takim przypadku zadziałałoby to:
Musisz także użyć &, który jest nieco logiczny i operator, aby uniknąć całego ff na początku.
źródło
Operator
~
(arytmetyczny) odwraca wszystkie bity , nazywany jest bitowym operatorem negacji:Tak więc w miejscach, w których kontekst jest arytmetyczny, zmienia liczbę ze wszystkimi bitami jako zerami na wszystkie bity jako jedności. A
$(( ~0 ))
konwertuje wszystkie bity reprezentacji liczb (zwykle obecnie 64 bity) na wszystkie.Liczba z wszystkimi z nich jest interpretowana jako liczba ujemna (pierwszy bit
1
)1
lub po prostu-1
.To samo dzieje się ze wszystkimi innymi liczbami, na przykład:
$(( ~1 ))
odwraca wszystkie bity:Lub binarnie:
1111111111111111111111111111111111111111111111111111111111111110
Który interpretowany jako liczba w reprezentacji dwóch jest następujący:
Ogólnie rzecz biorąc, równanie matematyczne człowieka
$(( ~n ))
jest równe$(( -n-1 ))
I (twoje pytanie):
źródło
Najpierw musisz zrozumieć, że 33 to liczba 32-bitowa lub 64-bitowa.
Dla wygody biorę ośmiobitową liczbę (= 1 bajt)
dziesiętna 33 jest w ośmiu bitach: 00100001, przerzucanie bitów daje wynik w wyniku 11011110.
Ponieważ bit najwyższego rzędu wynosi 1, jest to liczba ujemna.
Drukując liczbę ujemną, system drukuje znak minus, a następnie wykonuje uzupełnienie dwóch liczb ujemnych.
Uzupełnieniem dwóch jest: podrzucanie bitów i dodawanie 1.
11011110 ==> 00100001 ==> dodanie 1 ==> 00100010 powoduje, że liczba dziesiętna 34 jest za znakiem minus.
źródło