Wspólnie z moimi współpracownikami staramy się zrozumieć, dlaczego ktokolwiek miałby przeszkadzać w programowaniu liczb w bazie innej niż baza 10.
Zasugerowałem, że być może możesz zoptymalizować dłuższe równania, umieszczając zmienne we właściwej bazie, z którą pracujesz (na przykład, jeśli masz tylko zestawy 5 elementów bez resztek, możesz użyć podstawy 5), ale nie jestem pewien jeśli to prawda.
jakieś pomysły?
Odpowiedzi:
Typowym powodem pisania liczb w kodzie innym niż baza 10 jest to, że trochę się kręcisz.
Aby wybrać przykład w C (ponieważ jeśli C nadaje się do czegokolwiek, jest dobre do kręcenia bitów), powiedz, że jakiś format niskiego poziomu koduje 2-bitową i 6-bitową liczbę w bajcie
xx yyyyyy
:produkuje
W takich okolicznościach zapisanie stałych w kodzie szesnastkowym jest mniej mylące niż zapisanie ich w systemie dziesiętnym, ponieważ jedna cyfra szesnastkowa odpowiada dokładnie czterech bitom (pół bajtu; jeden „skubek”), a dwa do jednego bajtu: liczba
0x3f
ma wszystkie bity ustawiony w niskim skręcie, a dwa bity ustawione w wysokim skręcie.Możesz także napisać ten wiersz ósemkowy:
Tutaj każda cyfra odpowiada blokowi trzech bitów. Niektórym łatwiej jest myśleć, choć myślę, że w dzisiejszych czasach jest to dość rzadkie.
źródło
Głównym powodem, dla którego używam różnych baz jest to, że dbam o bity.
Jest o wiele łatwiejszy do odczytania
niż
Lub wyobraź sobie coś bardziej złożonego
w porównaniu do
Tutaj jest bardzo jasne, co ma na celu przykłady heksadecymalne, ponieważ hex jest po prostu bardziej zwartą formą binarną ... W przeciwieństwie do tego, base-10 (to, czego używamy) nie mapuje się tak dobrze na binarne.
Istnieją również inne bazy, z których można korzystać w niektórych językach. Znajdziecie bardzo mało wykorzystania baz innych niż binarne, szesnastkowe i dziesiętne. Niektórzy dziwni ludzie nadal używają ósemkowej, ale to najbardziej ezoteryczny program, jaki zobaczysz.
źródło
Jak zapewne wiesz, komputery oparte są na systemie binarnym - jest to baza 2.
Jest to łatwe do konwersji pomiędzy podstawą 2 i 4, 8 i 16 (i podobnych wielokrotności 2), utrzymując ten tłumaczenie w kodzie źródłowym może uczynić pracę z liczbami dużo łatwiejsze do rozumu temat.
W przypadku języków niskiego poziomu, takich jak asembler i C, może to zostać przetłumaczone bezpośrednio na operacje procesora (na przykład przesunięcie bitów w celu dzielenia i mnożenia), co oznacza, że użycie tych baz liczb kończy się znacznie szybszym kodem.
Dodatkowo, nie wszystkie operacje są operacjami numerycznymi - istnieją mapy bitów, w których musisz bezpośrednio manipulować bitami - użycie bazy 2 lub jednej z jej wielokrotności znacznie to ułatwia.
Jeśli chcesz dowiedzieć się więcej, polecam przeczytanie Code Charlesa Petzolda .
źródło
Być może, jeśli piszesz grę symulującą ekonomię jakiejś starożytnej cywilizacji korzystającej z systemu podstawowego 12.
źródło
Poza wysoce wyspecjalizowanymi programami dość rzadko używa się baz innych niż 10, 16 lub 2.
Podstawa 16 (szesnastkowa) jest użyteczna po prostu dlatego, że pełny zakres bajtu (0-255) może być reprezentowany przez dwie cyfry (0x00-0xFF), co może znacznie ułatwić pracę z surowymi zrzutami szesnastkowymi lub danymi binarnymi. Szesnastkowy jest również przydatny, gdy używa się masek bitowych z operatorami bitowymi, ponieważ dwucyfrowa korespondencja bajtów pomaga w czytelności.
Rzadziej baza 2 (binarna) może być również używana z operacjami bitowymi, ale wiele języków programowania nie obsługuje literałów base-2, a w każdym razie szesnastkowy jest znacznie bardziej zwięzły i czytelny.
Base-8 (ósemkowy) jest również czasami używany z powodu uprawnień do plików UNIX. Poza tym dość rzadko używa się baz innych niż 10 poza wysoce specjalistycznymi kontekstami matematycznymi.
źródło
Najczęstszym uzasadnionym powodem korzystania z innych baz jest łatwość konwersji na bazę 2: przekształcenie liczby binarnej base-8 lub base-16 w binarną jest banalne bez użycia kalkulatora poprzez zapamiętanie krótkiej tabeli zawierającej osiem lub szesnaście liczby:
Otwiera to wiele możliwości:
0xFF00FF
jest to magenta (czerwony + niebieski); zadanie jest znacznie trudniejsze, gdy zostaniesz mu przedstawiony16711935
źródło
Komputer (a ściślej kompilator) tak naprawdę nie dba o to, jakiej bazy liczb używasz w kodzie źródłowym. Najczęściej używane języki programowania obsługują bezpośrednio bazy 8 (ósemkowe), 10 (dziesiętne) i 16 (szesnastkowe). Niektóre oferują także bezpośrednie wsparcie dla liczb podstawowych (binarnych). Języki specjalistyczne mogą również obsługiwać inne bazy liczb. (Przez „bezpośrednie wsparcie” rozumiem, że pozwalają one na wprowadzanie liczb w tej bazie bez uciekania się do matematycznych sztuczek, takich jak przesunięcie bitów, mnożenie, dzielenie itp. W samym kodzie źródłowym. Na przykład C bezpośrednio obsługuje bazę 16 z jej
0x
prefiks numeru i zwykły zestaw cyfr szesnastkowych 0123456789ABCDEF. Teraz takie sztuczki mogą być przydatne, aby numer był łatwiejszy do zrozumienia w kontekście, ale tak długo, jak możesz wyrazić ten sam numer bez nich, robienie tego - lub nie - to tylko wygoda).W końcu jest to jednak nieistotne. Powiedzmy, że masz takie zdanie:
Celem jest utworzenie zmiennej całkowitej i zainicjowanie jej dziesiętną liczbą 10. Co widzi komputer?
Kompilator tokenizuje to i zdaje sobie sprawę, że deklarujesz zmienną typu
int
o nazwien
, i przypisujesz jej wartość początkową. Ale jaka jest ta wartość?Do komputera i ignorując problemy z porządkowaniem bajtów i wyrównaniem danych wejściowych dla wartości początkowej zmiennej jest
0x31 0x30
. Czy to oznacza, że wartość początkowa to 0x3130 (12592 w podstawie 10)? Oczywiście nie. Analizator składni języka musi nadal odczytywać plik w użytym kodowaniu znaków, więc po jego odczytaniu1
0
następuje zakończenie instrukcji. Ponieważ w tym języku zakłada się podstawę 10, to czyta się (wstecz) jako „0 jedynek, 1 dziesiątki, koniec”. Oznacza to, że wartość dziesiętna.Jeśli podaliśmy wartość w systemie szesnastkowym, a nasz język używa
0x
do określenia, że następująca wartość jest w systemie szesnastkowym, wówczas otrzymujemy:Kompilator widzi
0x
(0x30 0x78) i rozpoznaje to jako przedrostek base-16, więc szuka prawidłowego numeru base-16 po nim. Aż do terminatora instrukcji, czyta10
. Przekłada się to na 0 „jedynki”, 1 „szesnaście”, co daje wynik 16 w bazie 10. Lub 00010000 w bazie 2. Lub jakkolwiek chcesz to reprezentować.W obu przypadkach i ignorując optymalizacje dla uproszczenia, kompilator przydziela wystarczającą ilość miejsca do przechowywania wartości
int
zmiennej typu i umieszcza tam wartość odczytaną z kodu źródłowego w jakiejś tymczasowej zmiennej przechowywania. Następnie (prawdopodobnie znacznie później) zapisuje uzyskane wartości binarne do pliku kodu obiektowego.Jak widać, sposób pisania wartości liczbowych w kodzie źródłowym jest całkowicie nieistotny. Może to mieć bardzo niewielki wpływ na czasy kompilacji, ale wyobrażam sobie, że (ponownie, ignorując takie optymalizacje, takie jak buforowanie dysku przez system operacyjny), takie jak przypadkowe turbulencje wokół obracających się talerzy dysku, czasy dostępu do dysku, kolizje magistrali danych itp. mają znacznie większy efekt.
Podsumowując: nie martw się o to. Pisz liczby w bazie, którą obsługuje wybrany język programowania i która ma sens, w jaki sposób liczba będzie używana i / lub czytana. Spędziłeś znacznie więcej czasu na czytaniu tej odpowiedzi, niż kiedykolwiek będziesz mógł odzyskać w czasach kompilacji, będąc sprytnym co do tego, jakiej bazy liczb użyć w kodzie źródłowym. ;)
źródło
Oto kilka powodów, które jeszcze się nie pojawiły ...
x00 - Niektóre interfejsy API systemów operacyjnych i urządzeń sprzętowych oczekują, że argumenty będą szesnastkowe / binarne. Podczas kodowania takich interfejsów API łatwiej jest używać liczb w tym samym formacie, jakiego oczekuje interfejs API, zamiast konwertować je między różnymi bazami. Na przykład, aby wysłać bajt końca wiadomości do serwera lub wysłać wiadomość, aby zamknąć połączenie z kanałem komunikacyjnym.
x01 - Możesz chcieć, aby aplikacja reprezentowała znaki niedostępne na niektórych klawiaturach, takie jak znak praw autorskich (\ u00a9).
x02 - Aby niektóre stałe / literały zachowywały się (wizualnie) w różnych ustawieniach kultury, szczególnie gdy kod źródłowy / pliki są przenoszone między programistów z różnymi ustawieniami lokalnymi.
x03 - Aby kod był skomplikowany i skomplikowany - Dobrze, że C # nie obsługuje stałych ósemkowych!
źródło
Kluczową kwestią jest reprezentowanie jednego słowa wielkości komputera w rozsądny sposób. 6502 był 8-bitowym procesorem. 4004 był 4-bitowym procesorem.
W przypadku liczby 4 lub 8 bitowej działa dobrze. 4-bitowa liczba to pojedynczy znak szesnastkowy. 8-bitowa liczba (bajt) to dwie cyfry szesnastkowe. Systemy o sile 2 słów są dziś powszechnie postrzeganym standardem - 16-bitowy, 32-bitowy, 64-bitowy. Wszystkie te dzielnie dzielą się na 4, aby przedstawić je w systemie szesnastkowym.
Oktal (podstawa 8) był używany w systemach, w których rozmiar słowa wynosił 12, 24 lub 36. Używały go PDP8, IBM Mainframe i ICL 1900 dni. Te słowa były łatwiej reprezentowane za pomocą oktetów niż ograniczonego zakresu szesnastkowego (tak, dzielą się również na 4).
Najwyraźniej oszczędności przyniosły także zastosowanie numeracji podstawowej 8. Reprezentująca 12 bitów w BCD, pierwsza cyfra może wynosić tylko 0-4, ale druga, trzecia i czwarta mogą mieć wartość 0-9. Jeśli zrobiono to jako szesnastkowy, jeden ma 3 znaki szesnastkowe, ale każdy ma 16 możliwych wartości. Tańsze było wytwarzanie rurki Nixie, która miała tylko 0-7 niż 0-9 (z dodatkową logiką dla BCD) lub 0-F dla szesnastkowej.
Nadal widać liczbę ósemkową z uprawnieniami do plików unix (755, 644), w których właściciel, grupa i świat mają po 3 bity reprezentujące uprawnienia.
W świecie matematyki czasami robi się dziwne rzeczy z różnymi podstawami. Na przykład słaba sekwencja Goodsteina z projektu euler 396 ... lub coś prostszego z liczbami palindromicznymi . Istnieje pewna właściwość liczby w bazie N, że liczba będąca wielokrotnością N - 1 będzie miała swoje cyfry sumujące się do wielokrotności N - 1 . Ponadto, jeśli N - 1 jest kwadratem idealnym, ta właściwość istnieje również dla sqrt ( N - 1 ). Ma to pewne zastosowania w niektórych problemach matematycznych.
źródło
W branży finansowej istnieje schemat identyfikacyjny, który skutecznie stanowi podstawę 36 . Wykorzystuje cyfry 0–9 i litery BZ do reprezentowania cyfr o wartości 0–35. Pomija samogłoski, aby zapobiec generowaniu wstrętnych nazw.
Nie jest to jednak idealne. Był czas, kiedy jedna niefortunna firma miała identyfikator
B000BZ
.źródło
Powód 1: ponieważ wszystkie liczby na poziomie obwodu są przedstawione w podstawie 2 (przełącznik elektryczny jest włączony lub wyłączony). Powód # 2: ponieważ na poziomie wyższym niż rzeczywiste obwody bity są pogrupowane w bajty, a bajty mogą być łatwo reprezentowane jako dwie cyfry szesnastkowe, kiedy to potrzeba 3 cyfr dziesiętnych (i pewnej walidacji) do przedstawienia wszystkich możliwych wartości bajt.
Jeśli więc pracujesz na tych poziomach (lub przybliżasz je w niektórych zarządzanych środowiskach), łatwiej jest pracować w systemie binarnym lub szesnastkowym niż dziesiętnym. Sytuacje, w których byś to zrobił, są różne, ale zazwyczaj nie są to sytuacje, w których potrzebujesz jedynie podstawowej arytmetyki.
źródło
Jednym z obszarów, w którym bardzo często używane są liczby podstawowe 16 (szesnastkowe), jest określanie koloru, szczególnie w przypadku korzystania z HTML / CSS w Internecie. Kolory, których używamy na wyświetlaczach cyfrowych, są określane za pomocą kombinacji 3 wartości intensywności dla 3 kolorów „podstawowych” (RGB - czerwony, zielony, niebieski), które są mieszane, aby utworzyć dowolny z 16 milionów wyświetlanych kolorów (przy użyciu koloru 24-bitowego ).
Na przykład, pełne natężenie zielonego heks byłoby
0x00ff00
i65280
w systemie dziesiętnym. Teraz wyobraź sobie, starając się „ręcznie” mix kolor w twojej głowie, który ma równe części czerwony i niebieski, powiedzmy w połowie intensywności, aby utworzyć ładny fioletowy :) W hex miałoby to być napisane po prostu0x800080
podczas gdy wartość dziesiętna to byłoby8388736
. To staje się jeszcze łatwiejsze przy pracy z odcieniami szarości - 50% szarości jest0x808080
(hex) i8421504
(po przecinku), 75% to0xC0C0C0
i12632256
, i tak dalej.Korzystanie z heksów jest o wiele bardziej intuicyjne i każdy, kto zna się na tym użyciu koloru, będzie mógł natychmiast „odgadnąć” kolor, patrząc na wartość heksadecymalną. Jest również o wiele mniej podatny na błędy, jeśli trzeba wielokrotnie używać tego samego koloru (co zwykle ma miejsce).
Sprawdź dowolną stronę internetową (w szczególności CSS), aby dowiedzieć się więcej o użyciu heksadecymalnym: D
UWAGA: W CSS wartości szesnastkowe są zapisywane przy użyciu
#
prefiksu, na przykład:#00ff00
dla zieleni, a czasami są również skracane do zaledwie trzech cyfr, np.#0f0
Dla zieleni.źródło
W przypadku niektórych algorytmów podstawa 2 ma większy sens niż cokolwiek innego. Na przykład, czy wolałbyś napisać funkcję przechodzącą przez drzewo binarne lub drzewo 10-arytowe?
Częściej jednak używana jest podstawa 2, ponieważ w ten sposób komputery niemal powszechnie reprezentują swoje liczby. To znaczy że:
Ponadto zawsze istnieje rzadka aplikacja, która z natury wymaga nieparzystej podstawy, która nie może być ani 2, ani 10.
źródło
2
postaci używasz?Jest to szczerze preferencja, jeśli z jakiegoś powodu masz polidaktyczność i masz 11 palców lub lubisz liczenie palcami u nóg, więc lubisz pracować w bazie 20, to wszystko zależy od ciebie. Ale zdaj sobie sprawę, że na temat uniwersalności, że większość z nas, którzy codziennie mają do czynienia z bitami i bajtami, zostanie naprawdę zaznaczona, jeśli otrzymamy coś, co robi bitową manipulację w bazie 19.
POWODY DLA PODSTAWY x
Baza 10 - Model wszystkich naszych rzeczy, ponieważ mamy 10 cyfr liczących (stopy są dziwne i śmierdzą, więc ich nie używamy).
Baza 2 - komputery używają tego do bitów (włączanie / wyłączanie). Jest to związane z czytelnymi poziomami napięcia propagowanymi przez bramki / tranzystory / kondensatory.
Baza 8 - Stara, dawniej, kiedy komputery nie były super ogromne (lub wstecz, gdy były kosmiczne) to było dobre na coś takiego (nie podoba mi się to ani trochę)
Baza 16 - Dobra do pokazywania górnych i dolnych części bajtu w celu manipulowania bitami. Jest to bardzo przydatne w świecie sprzętu osadzonego / fpga /.
NORMALNE PODSTAWY W KOMPUTERACH
Na wstępie mogę powiedzieć dokładnie, jak „włączony” jest kolor w heksadecymalnej wartości RGB, która jest mi podana, w konsekwencji może być reprezentowany w jednym int w sprzęcie, a następnie z pewnymi przesunięciami może zostać mi zwrócony łatwy w obsłudze, 1 złożony kolor = 1 punkt danych, który jest przydatny przy przetwarzaniu dużych obrazów przy ograniczonej pamięci. Porównaj to z podstawową reprezentacją 10, możesz dodać je wszystkie i zapisać je w liczbach, ale która to liczba, która może, a może R to czas 10000, G to 100, a B to jego własna przestrzeń, to dużo operacji matematycznych , zwykle mnożenie kosztuje więcej cykli niż przesunięcie, więc twój następny element danych jest już w kolejce, zanim skończysz przetwarzać ostatni kawałek, ups, to już nie ma.
Czasami po prostu lepiej jest pracować w bazie 2, 8 lub 16. W przypadku większości maszyn mnożenie przez 2 to tylko niewielka zmiana, te są super szybkie, to samo z dzieleniem przez 2.
Aby jeszcze bardziej wyjaśnić ideę kręcenia się po kawałku. Podczas pracy w środowisku osadzonym wiele razy potrzebowałem dostępu do szeregu lampek, przełączników lub innych elementów zmapowanych w rejestrze.
W takim przypadku przypisanie do każdego przełącznika całego znaku, bajtu lub liczby int byłoby nieefektywne i głupie, przełącznik lub lampka ma 2 pozycje - włączanie i wyłączanie - dlaczego miałbym przypisywać coś, co ma do 256 pozycji lub 2 ^ 16 pozycje itp. Każde światło w tablicy może mieć 1 bit pasujący do 8 lub 16 lub 32 lub 64 lub 128 (szerokość twojego typu danych) w jednym słowie / rejestrze. Wydajność przestrzeni jest potrzebna i raczej mile widziana.
Używanie czegokolwiek, co stanowi podstawę 2 ^ n, w programowaniu do obsługi danych RGB, wielu danych sygnałowych - GPS, audio, ascii itp. - jest znacznie prostsze w trybie szesnastkowym, binarnym i ósemkowym, ponieważ jest to sposób, w jaki jest reprezentowany w maszynie i można łatwiej rozpoznać, co jest prezentowane i jak nim manipulować.
KORZYSTANIE Z NIESAMOWITEJ PODSTAWY
Nie ma wydajności, chyba że ją kodujesz. Potrzebujesz bazy 11, musisz ustawić dla niej typ danych i przeciążać operatorów, aby obsłużyć ich reprezentację dla użytkownika. Nie widzę powodu, dla którego system zawierający 5 przedmiotów i tylko posiadający wielokrotności 5 przedmiotów musiałby zostać przekształcony w matematykę pięciu przedmiotów. Co więcej, lepiej módlcie się, aby ktokolwiek zdecydował się napisać swój kod dla bazy 271, dobrze go udokumentował, lub można poświęcić więcej czasu na jego zrozumienie, niż jest to warte, tworząc bazę 271, ponieważ wszystkie elementy są wielokrotnością 271.
źródło
W dawnych czasach komputerów mieliśmy wiele wyświetlaczy, które mogły pokazywać cyfry 0–9, ale nie mieliśmy jeszcze AF.
http://ad7zj.net/kd7lmo/images/ground_nixie_front.jpg jest jednym z takich przykładów ...
Oktalowy pasuje naprawdę ładnie na tych wyświetlaczach i był łatwiejszy niż binarny lub dziesiętny.
źródło
Dziwi mnie, że wszystkie pozostałe odpowiedzi nie wspominały o dwóch bardzo częstych zastosowaniach w obliczeniach dla alternatywnych baz:
Kompresja : Często pożądane jest przedstawienie liczby binarnej, dziesiętnej lub szesnastkowej w większej bazie, aby skrócić reprezentację. Na przykład robią to wszystkie skróty do bitów, takie jak bit.ly. Lub możesz to zrobić, aby skrócić identyfikator GUID do użycia w adresie URL.
źródło