Ile wynosi −5 w ośmiobitowym kodzie U2?
11111011 11111011, czyli 0xFB.
Wpisz liczbę całkowitą ze znakiem i otrzymaj naraz kod znak-moduł, U1, U2 oraz kod z nadmiarem, od 4 do 64 bitów. Możesz też wkleić ciąg bitów albo bajt szesnastkowy i zobaczyć wszystkie pięć odczytów obok siebie.
Wpisz liczbę całkowitą ze znakiem. Cztery reprezentacje liczone są naraz — nie musisz z góry wiedzieć, której używa Twój system.
| Kod | Bity | Szesnastkowo |
|---|---|---|
| Znak-moduł | 1000 0101 | 85 |
| Kod U1 | 1111 1010 | FA |
| Kod U2 | 1111 1011 | FB |
| Kod z nadmiarem | 0111 1011 | 7B |
Znak-moduł i kod U1 poświęcają po jednym układzie bitów na zero ujemne, więc mieszczą o jedną wartość mniej niż kod U2 i nie sięgają liczby najbardziej ujemnej.
Znalazłeś bajt w zrzucie pamięci albo w rejestrze i nie wiesz, jak należy go odczytać. Wklej go i zobacz od razu, co znaczy w każdej interpretacji — która z nich jest właściwa, zależy od systemu, który go wyprodukował, więc pokazujemy wszystkie.
| Odczyt jako | Wartość |
|---|---|
| Bez znaku | 251 |
| Znak-moduł | -123 |
| Kod U1 | -4 |
| Kod U2 | -5 |
| Kod z nadmiarem | 123 |
Policzona tym samym silnikiem, którego używa narzędzie powyżej, więc te wartości nie mogą się z nim rozjechać.
| Dziesiętnie | Znak-moduł | Kod U1 | Kod U2 | Kod z nadmiarem | Szesnastkowo |
|---|---|---|---|---|---|
| 127 | 0111 1111 | 0111 1111 | 0111 1111 | 1111 1111 | 7F |
| 100 | 0110 0100 | 0110 0100 | 0110 0100 | 1110 0100 | 64 |
| 10 | 0000 1010 | 0000 1010 | 0000 1010 | 1000 1010 | 0A |
| 5 | 0000 0101 | 0000 0101 | 0000 0101 | 1000 0101 | 05 |
| 1 | 0000 0001 | 0000 0001 | 0000 0001 | 1000 0001 | 01 |
| 0 | 0000 0000 | 0000 0000 | 0000 0000 | 1000 0000 | 00 |
| -1 | 1000 0001 | 1111 1110 | 1111 1111 | 0111 1111 | FF |
| -5 | 1000 0101 | 1111 1010 | 1111 1011 | 0111 1011 | FB |
| -10 | 1000 1010 | 1111 0101 | 1111 0110 | 0111 0110 | F6 |
| -100 | 1110 0100 | 1001 1011 | 1001 1100 | 0001 1100 | 9C |
| -127 | 1111 1111 | 1000 0000 | 1000 0001 | 0000 0001 | 81 |
| -128 | — | — | 1000 0000 | 0000 0000 | 80 |
| Szerokość | Kod U2 / kod z nadmiarem | Znak-moduł / kod U1 |
|---|---|---|
| 4 | -8 … 7 | -7 … 7 |
| 8 | -128 … 127 | -127 … 127 |
| 16 | -32768 … 32767 | -32767 … 32767 |
| 32 | -2147483648 … 2147483647 | -2147483647 … 2147483647 |
| 64 | -9223372036854775808 … 9223372036854775807 | -9223372036854775807 … 9223372036854775807 |
Zbudowane i zweryfikowane przez zespół inżynierski Go Tools.
11111011 11111011, czyli 0xFB.
-128 … 127 Od −128 do 127 w kodzie U2; od −127 do 127 w kodzie znak-moduł i w kodzie U1.
wartość − 2^n Jeśli najstarszy bit to 0, czytaj go jak liczbę bez znaku; jeśli to 1, odejmij 2^n od odczytu bez znaku.
−1 albo 255 −1 jako bajt ze znakiem, 255 jako bajt bez znaku. Same bity tego nie przesądzają.
Kod uzupełnień do dwóch odpowiada na pytanie sprzętowe, a nie matematyczne: jak zapisać liczby ujemne, żeby zbudowany już sumator dalej działał? Sztuczka polega na przedstawieniu −x układem bitów odpowiadającym 2^n − x. Dodawanie zawija się wtedy modulo 2^n i trafia we właściwy wynik bez żadnego przypadku szczególnego dla znaków, dlatego odejmowanie nie wymaga osobnego układu.
Wynikają z tego dwie rzeczy i obie pojawiają się w prawdziwych błędach. Po pierwsze, zakres jest niesymetryczny: osiem bitów obejmuje od −128 do 127, a nie do 128, bo układy bitów trzeba jakoś rozdzielić, a nie ma zera ujemnego, które wyrównałoby rachunek. Po drugie, znak nie jest flagą, którą da się odciąć — najstarszy bit w 11111011 to 1, ale wartość wynosi −5, a nie −123, więc odczytanie liczby ujemnej oznacza interpretację całego słowa, a nie spojrzenie na jeden bit.
Znak-moduł i kod U1 to dwa projekty, które przegrały. Nadal warto je znać, bo liczby zmiennoprzecinkowe IEEE 754 zachowały układ typu znak-moduł i bo dopiero to porównanie sprawia, że kod U2 wygląda na rozwiązanie nieuchronne, a nie dowolne.
// -5 as an 8-bit byte, three ways to arrive at the same pattern 0b00000101 // 5 ~0b00000101 // 11111010 ones' complement of 5 ~0b00000101 + 1 // 11111011 two's complement = -5 // In JavaScript the width matters: bitwise operators are 32-bit, // so anything wider has to go through BigInt. BigInt.asIntN(8, 0xFBn) // -5n BigInt.asUintN(8, -5n) // 251n BigInt.asIntN(64, 0xFFFFFFFFFFFFFFFBn) // -5n // C23 made two's complement mandatory for signed integers. // Before that, the other two encodings were legal but unused.
Znak-moduł, kod U1, kod U2 i kod z nadmiarem liczone są wspólnie. Kod z nadmiarem to ten, który większość kalkulatorów pomija, a zarazem ten, którego wciąż używają noty katalogowe przetworników ADC.
Wklej bity albo zapis szesnastkowy, który naprawdę masz, i zobacz wszystkie pięć odczytów, razem z odczytem bez znaku. Tego kierunku potrzebujesz, gdy zrzut pamięci nie zgadza się z liczbą podawaną przez urządzenie.
Każda wartość liczona jest na typie BigInt, więc 0xFFFFFFFFFFFFFF9C daje −100, a nie cokolwiek, co wyszłoby z obcięcia do 32 bitów.
Przy szerokości 8 wartość −128 nie ma postaci w kodzie znak-moduł ani w kodzie U1. Tabela wprost to zapisuje, zamiast drukować układ bitów, który tej liczby nie oznacza.
Wpisz 0, a zobaczysz drugi układ bitów zera w kodzie znak-moduł i w kodzie U1 — to najbardziej przekonujący pojedynczy argument za tym, dlaczego wygrał kod U2.
Tabela porównawcza dla 8 bitów i zakresy dla poszczególnych szerokości powstają podczas budowania strony, w tym samym silniku, który obsługuje pola interaktywne, więc nie mogą się z nim rozjechać.
BigInt.asIntN, int.from_bytes(..., signed=True) w Pythonie i typy o ustalonej szerokości w C dają rozstrzygającą odpowiedź dla kodu, który właśnie piszesz. Ich używaj w kodzie; tej strony używaj wtedy, gdy masz wartość przed sobą i żadnego otwartego interpretera.
Pokazuje wartość zgodnie z typem zadeklarowanym w programie, czyli dokładnie tą informacją, której brakuje samemu układowi bitów. Nie pomoże, gdy bajty przyszły łączem bez zadeklarowanego typu — a właśnie do tego przypadku służy ta strona.
Przelicza między systemami liczbowymi, ale wyłącznie dla wartości nieujemnych — liczby ujemne są tam jawnie odrzucane, bo sam system liczbowy nie ma zdania o tym, jak zapisuje się znak. Reprezentacja ze znakiem to zadanie tej strony; konwertera liczbowego używaj do modułów.
Odpowiednik dla liczb zmiennoprzecinkowych. Zachowuje układ typu znak-moduł zamiast kodu U2 i przesuwa wykładnik o 2^(e−1)−1, więc obie strony odpowiadają na inne pytania dotyczące tego samego słowa pamięci.
-5, szerokość 8
znak-moduł 1000 0101 kod U1 1111 1010 kod U2 1111 1011 (0xFB) kod z nadmiarem 0111 1011
Trzy kody zgadzają się co do bitu znaku i różnią się we wszystkim pozostałym. Tym, co naprawdę siedzi w int8_t w języku C, jest wyłącznie wiersz z kodem U2.
0xFB, szerokość 8
bez znaku 251 znak-moduł -123 kod U1 -4 kod U2 -5 kod z nadmiarem 123
-128, szerokość 8
znak-moduł brak reprezentacji kod U1 brak reprezentacji kod U2 1000 0000 (0x80) kod z nadmiarem 0000 0000
Znak-moduł i kod U1 poświęcają po jednym układzie bitów na zero ujemne, więc sięgają od −127 do 127 i nie dochodzą do −128. Narzędzia, które wypisują tu jakiś bajt, po prostu się mylą.
0xFFFFFFFFFFFFFF9C, szerokość 64
kod U2 -100 bez znaku 18446744073709551516
Wszystko szersze niż 32 bity trzeba liczyć na typie BigInt. Operatory |, << i >>> w JavaScripcie po cichu obcinają wynik do 32 bitów i właśnie dlatego część kalkulatorów online podaje tu błędną odpowiedź zamiast zgłosić błąd.
4, 8, 16, 32 albo 64. To nie jest ustawienie wyglądu — te same bity znaczą przy różnych szerokościach różne liczby, więc pomyłka zmienia odpowiedź.
Podaj liczbę całkowitą, razem ze znakiem minus. Cztery kody odświeżają się w trakcie pisania, a przy każdym pojawia się też postać szesnastkowa.
Wklej ciąg binarny albo wartość zaczynającą się od 0x w polu odczytu odwrotnego, aby zobaczyć, co ten konkretny układ bitów znaczy w każdej interpretacji, łącznie z odczytem bez znaku.
Strona sygnalizuje dwa przypadki, na których najłatwiej się potknąć: wartość najbardziej ujemną bez postaci w kodzie znak-moduł i w kodzie U1 oraz zero mające w tych dwóch kodach drugi układ bitów.
Negacja bitów daje kod U1. Zatrzymanie się na tym kroku różni się o jeden od kodu U2, a błąd łatwo przeoczyć, bo wynik nadal wygląda na wiarygodną liczbę ujemną.
5 = 00000101 ~5 = 11111010 <- ones' complement, not -5
5 = 00000101 ~5 = 11111010 ~5 + 1 = 11111011 <- -5 in two's complement
JavaScript obcina argumenty operatorów bitowych do 32 bitów. Górna połowa znika bez żadnego błędu, więc wynik jest błędny, a nie brakujący.
0xFFFFFFFFFFFFFFFB // 18446744073709552000 -- the literal is already rounded ~0xFFFFFFFFFFFFFFFB + 1 // 0 -- silently wrong, expected -5
BigInt.asIntN(64, 0xFFFFFFFFFFFFFFFBn) // -5n
Poszerzanie przez dopełnienie zerami zachowuje liczbę tylko wtedy, gdy jest dodatnia. Przy wartości ujemnej bit znaku trzeba powielić na wszystkich nowych bitach.
int8 0xFB (-5) int16 0x00FB (251) <- zero-extended
int8 0xFB (-5) int16 0xFFFB (-5) <- sign-extended
Na ośmiu bitach −128 nie ma reprezentacji ani w kodzie znak-moduł, ani w kodzie U1, bo oba poświęcają jeden układ bitów na zero ujemne. Wypisanie dla niej 10000000 miesza odpowiedź z kodu U2 z kodem, który tej liczby nie potrafi wyrazić.
-128 sign-magnitude: 10000000 <- that pattern means -0
-128 sign-magnitude: no representation at width 8 -128 two's complement: 10000000
0xFF9C. Bez znaku daje to 65436, a to nie jest żadna temperatura. Przy szerokości 16 wiersz kodu U2 pokazuje −100, a przy współczynniku skali 0,1 °C czujnik mówi Ci −10,0 °C.n−1 bitów to moduł, czytany jak zwykła liczba bez znaku. Zakres sięga od −(2^(n−1)−1) do 2^(n−1)−1, jest symetryczny i ma dwa zera. To układ, którego IEEE 754 używa dla liczb zmiennoprzecinkowych.2^n − 1 − x. Ten sam zakres i te same dwa zera co w kodzie znak-moduł. Dodawanie wymaga przeniesienia obiegowego, a to właśnie tę komplikację usuwa kod U2. W angielskich nazwach położenie apostrofu nie jest literówką: ones' complement odnosi się do słowa złożonego z samych jedynek, a two's complement do pojedynczej potęgi dwójki.−x zapisywana jest jako 2^n − x. Zakres sięga od −2^(n−1) do 2^(n−1)−1, jest celowo niesymetryczny i ma jedno zero. Dodawanie, odejmowanie i mnożenie młodszego słowa są niezależne od znaku i to jest cały powód, dla którego ten kod wygrał.value + 2^(n−1), więc −2^(n−1) staje się samymi zerami, a układy bitów sortują się w tej samej kolejności co kodowane przez nie wartości. Równa się układowi z kodu U2 z odwróconym najstarszym bitem. Uwaga na nazewnictwo: pola wykładnika w IEEE 754 mają przesunięcie 2^(e−1)−1, o jeden mniejsze niż nadmiar używany tutaj.&, |, ~ oraz przesunięć na liczby całkowite 32-bitowe przed działaniem i z powrotem po nim, więc wartość 64-bitowa traci górną połowę bez zgłoszenia jakiegokolwiek błędu. Każda konwersja na tej stronie wykonywana jest zamiast tego na liczbach całkowitych o dowolnej precyzji i dlatego skrajne wartości 64-bitowe wychodzą tu dokładnie.−(−128) dla bajtu ze znakiem nadal daje −128. Każdy kod liczący wartość bezwzględną musi mieć pomysł na to wejście, a każdy zestaw testów powinien je zawierać.0xFB do pola 16-bitowego jako 0x00FB zamienia −5 w 251. Poszerzenie wartości ze znakiem oznacza powielenie bitu znaku, co daje 0xFFFB.BigInt.asIntN w JavaScripcie, int.from_bytes(..., signed=True) w Pythonie i typy o ustalonej szerokości w C mówią wprost, o co im chodzi, i obsługują przypadki brzegowe. To ręcznie pisane ~x + 1 jest źródłem błędów szerokości.2^n − x, dzięki czemu dodawanie i odejmowanie korzystają z tego samego układu scalonego, a oś liczbowa ma dokładnie jedno zero. 00000101 → 11111010 → 11111011. Sama negacja daje kod U1 i dlatego oba zapisy zawsze różnią się o jeden. n bitach obejmuje zakres od −2^(n−1) do 2^(n−1)−1, bo nie marnuje jednego układu bitów na zero ujemne, jak robią to znak-moduł i kod U1. Ta dodatkowa pozycja przypada stronie ujemnej. int8_t albo uint8_t. value + 2^(n−1), więc wartość najmniejsza to same zera, a posortowanie surowych układów bitów jak liczb bez znaku porządkuje również wartości ze znakiem. Spotkasz go na wyjściach przetworników ADC i DAC oraz w formatach próbek dźwięku. Uwaga: wykładniki w IEEE 754 mają inne przesunięcie — 2^(e−1)−1, a nie 2^(e−1) — więc nie przenoś tej liczby między jednym a drugim. 65436, podczas gdy urządzenie miało na myśli wartość −100 w kodzie U2. Wklej tutaj 65436 jako szesnastkowe 0xFF9C przy szerokości 16, a wiersz kodu U2 pokaże odczyt zgodny z zamierzeniem. ~x + 1 po cichu gubi górną połowę wartości 64-bitowej i podaje wynik wiarygodny, ale błędny. To narzędzie wszędzie korzysta z typu BigInt i dlatego tutejsze wiersze 64-bitowe zgadzają się z tym, co pokazuje Twój debugger. 00000000, jak i 10000000 oznaczają zero; w kodzie U1 są to 00000000 i 11111111. Dwie wartości, które powinny być równe, mogą więc różnić się bit po bicie. Kod U2 ma jedno zero, co usunęło całą klasę przypadków szczególnych w sprzęcie. Narzędzia konwersji
Konwertuj między systemami binarnym, szesnastkowym, dziesiętnym i ósemkowym (2–36) w czasie rzeczywistym. Bezpłatnie i prywatnie — w przeglądarce.
Narzędzia konwersji
Konwertuj uprawnienia plików Linux między zapisem ósemkowym (755, 644) a symbolami rwx. Gotowe polecenia chmod i ostrzeżenia przed ryzykownymi trybami takimi jak 777 — za darmo, w całości w przeglądarce.
Narzędzia konwersji
Konwertuj HEX na RGB, HSL, OKLCH, OKLAB i CMYK w przeglądarce — skopiuj dowolny format jednym kliknięciem. Darmowy, bez rejestracji, kolory nigdy nie opuszczają strony.
Narzędzia konwersji
Konwertuj kolory HEX na CMYK w przeglądarce. Naiwne przybliżenie oparte na sRGB do podglądu druku. Bezpłatny, bez rejestracji, kolory zostają lokalnie.
Narzędzia konwersji
Konwertuj dowolny kolor HEX na HSL w przeglądarce — obsługa 3-, 6- i 8-cyfrowego HEX z kanałem alfa. Bezpłatny, natychmiastowy, bez rejestracji, kolory nigdy nie opuszczają strony.
Narzędzia konwersji
Konwertuj HEX na OKLCH pod tokeny projektowe Tailwind v4. Na żywo, percepcyjnie jednorodne wyjście z ostrzeżeniami o gamucie Display P3. Darmowy, tylko w przeglądarce.