Dlaczego tak wiele języków traktuje liczby zaczynające się od 0 jako ósemkowe?

22

Czytałem Gdzie przydatne są ósemki? i wygląda na to, że ósemki były kiedyś użyteczne.

Wiele języków traktuje liczby poprzedzające 0 jako liczbę ósemkową, więc literał 010to w rzeczywistości 8. Kilka z nich to JavaScript, Python (2.7) i Ruby.

Ale tak naprawdę nie rozumiem, dlaczego te języki wymagają liczby ósemkowej, zwłaszcza gdy bardziej prawdopodobne jest, że użycie notacji będzie oznaczać liczbę dziesiętną z zbędnym 0.

JavaScript jest językiem po stronie klienta, ósemkowy wydaje się dość bezużyteczny. Wszystkie trzy są całkiem nowoczesne w innym znaczeniu i nie sądzę, że byłoby dużo kodu używającego notacji ósemkowej, który zostałby zepsuty przez usunięcie tej „funkcji”.

Tak więc moje pytania to:

  • Czy jest jakiś sens tych języków obsługujących literały ósemkowe?
  • Jeśli konieczne jest użycie literału ósemkowego, dlaczego nie użyć czegoś takiego 0o10? Po co kopiować starą notację, która zastępuje bardziej użyteczny przypadek użycia?
Manishearth
źródło
24
Czy jako odpowiedź zaakceptujesz „mylenie młodych ludzi podczas wywiadu”?
yannis
11
zgodny ze składnią C + ślepe kopiowanie
maniak ratchet
1
@Manishearth C odziedziczył go po przodkach. Java ma to, ponieważ C ma to. Większość ma to, ponieważ C i Java.
Ingo
2
Nadal widać ósemkowe zmiany chmodpoprawności pliku Unix: z 0666 lub 0777 dla grup 3 bitów dla użytkownika, grupy i innych: odczyt, zapis, plik wykonywalny.
Joop Eggen
3
@Llepwryd W starszych przeglądarkach parseInt('010')rzeczywiście zwróciło 8, stąd wszystkie porady, których należy zawsze używać parseInt(foo, 10)(i nadal jest to dla mnie nawyk)
Izkata

Odpowiedzi:

34

Ślepe kopiowanie C, tak jak powiedział grzechotnik w swoim komentarzu

Zdecydowana większość „projektantów języków” w dzisiejszych czasach nigdy nie widziała nic poza C i jego kopiami (C ++, Java, JavaScript, PHP i prawdopodobnie kilkadziesiąt innych, o których nigdy nie słyszałem). Nigdy nie dotknęli FORTRAN, COBOL, LISP, PASCAL, Oberon, FORTH, APL, BLISS, SNOBOL, żeby wymienić tylko kilka.

Dawno, dawno temu, kontakt z wieloma językami programowania był OBOWIĄZKOWY w programie nauczania informatyki i nie obejmował liczenia C, C ++ i Java jako trzech oddzielnych języków.

Oktal był używany wcześniej, ponieważ ułatwiał czytanie wartości instrukcji binarnych. Na przykład PDP-11, PODSTAWOWO, miał 4-bitowy kod operacji, 2 3-bitowe numery rejestrów i 2 3-bitowe pola mechanizmu dostępu. Wyrażenie tego ósemkowego uczyniło wszystko oczywistym.

Ze względu na wczesne skojarzenie C z PDP-11 włączono notację ósemkową, ponieważ w tym czasie była bardzo powszechna na PDP-11.

Inne maszyny miały zestawy instrukcji, które nie były dobrze odwzorowane na hex. CDC 6600 miał 60-bitowe słowo, przy czym każde słowo zawierało zwykle od 2 do 4 instrukcji. Każda instrukcja miała 15 lub 30 bitów.

Jeśli chodzi o czytanie i pisanie wartości, jest to rozwiązany problem, ze znanymi najlepszymi praktykami branżowymi, przynajmniej w przemyśle obronnym. DOKUMENTUJ swoje formaty plików. Nie ma dwuznaczności, gdy format jest dokumentowany, ponieważ dokument MÓWI, czy patrzysz na liczbę dziesiętną, liczbę szesnastkową czy liczbę ósemkową.

Uwaga: jeśli twój system I / O domyślnie ma wiodącą 0, czyli ósemkową, musisz użyć innej konwencji na wyjściu, aby oznaczyć wartości szesnastkowe. To niekoniecznie jest wygrana.

Moim osobistym zdaniem Ada zrobiła to najlepiej: 2 # 10010010 #, 8 # 222 #, 16 # 92 # i 146 wszystkie przedstawiają tę samą wartość. (Zapewne dostanę co najmniej trzy opinie poniżej, tylko za wspomnienie o Adzie.)

John R. Strohm
źródło
11
Zgłosiłem się za wspomnienie o Ada ... tylko żartowałem
kufi
12
Ciekawi mnie, jak doszedłeś do wniosku, że znacznie więcej niż 50% „projektantów języków” - dlaczego przytakuje? - nie mają doświadczenia z niczym innym niż potomkowie C. Spędziłem dobre szesnaście lat swojego życia, rozmawiając codziennie z profesjonalnymi projektantami języków i żaden z nich nie pasuje do twojego opisu.
Eric Lippert
JavaScript został opisany jako „chcemy zrobić seplenienie w przeglądarce”, aby zainteresować jego projektanta, jeśli dobrze pamiętam ten wywiad ...
Izkata
2
@Izkata: Rzeczywiście, Waldemar Horwat powiedział mi kiedyś, że postrzega JavaScript jako zasadniczo Common Lisp o składni podobnej do C. W rzeczywistości Waldemar zdefiniował metaljęzyk, napisał interpreter dla swojego metalingu w Common Lisp, a następnie napisał specyfikację JavaScript w swoim metalingu, umożliwiając mu w rzeczywistości uruchomienie specyfikacji. To była sprytna technika.
Eric Lippert
Dlaczego użyto 0? Czy nie ma sensu używać znaków nienumerycznych? Czy standard ANSI po prostu nie przewidywał błędów powodowanych przez liczby, które mają być dziesiątą bazą?
Old Badman Gray,
6

Dostają to od C. Po co kopiować? Ponieważ podstawową implementacją wszystkich 3 jest C. Domyślna implementacja Pythona to CPython . Ruby został wybudowany w C , jak również. JavaScript jest tutaj najciekawszym przypadkiem. Jest uruchamiany w przeglądarce. Chcesz zgadnąć, w czym została napisana pierwsza przeglądarka internetowa ?

Dlaczego więc wszystkie trzy z tych języków byłyby implementowane w C? Ponieważ wszystkie pochodzą z systemów UNIX. Jest to więc przypadek konwencji napędzanej przez ekosystem. Perl też to robi. Lua prawdopodobnie by to zrobił, gdyby Lua użył liczb całkowitych zamiast podwójnych .

Jest to więc kwestia środowiska, w jakim te języki są napisane w C, więc biorą swoje konwencje z C. Dobrym towarzyszącym wnioskiem jest Visual Basic, który zamiast tego używa & O. O ile jest to potrzebne, wydaje się, że jest to bardziej nieszczelna konwencja zmieniająca się w konwencję niż cokolwiek innego.

Inżynier świata
źródło
Czy Mosaic obsługuje JavaScript? Jeśli nie, to jak wspomnieć o tym, że jest istotne?
svick
2
@svick Jest to podstawa dla Netscape Navigator, który to zrobił.
Inżynier świata
2

Spójność ma wartość. Jeśli nie możesz wiarygodnie określić, w jaki sposób liczba zostanie przetłumaczona, będziesz mieć prawdziwe problemy z użyciem wartości w różnych kontekstach.

Oznacza to również, że nie musisz pisać własnego parsera. Wykorzystanie dobrze przetestowanych procedur bibliotecznych ma wielką wartość.

Również jeśli nie obsługujesz wiodącej składni 0, nie masz prostego sposobu na pisanie wartości ósemkowych.

Chociaż nie polegamy tak bardzo na liczbach ósemkowych, jak kiedyś, wciąż są one cenne. Chociaż te same wyniki można uzyskać za pomocą liczb szesnastkowych, w niektórych kontekstach ósemka jest łatwiejsza do zrozumienia.

Do tej pory widziałem tylko jedno użycie zer wiodących w liczbach dziesiętnych. Oznacza to wyświetlanie i wprowadzanie pól dziesiętnych o stałej długości, takich jak numery identyfikacyjne. Minęły lata, odkąd widziałem takie pola z wiodącym zerem. Zmniejsza to dostępne wartości o 10%, ale eliminuje problem polegający na tym, że użytkownicy często pomijają początkowe zera podczas ich wprowadzania.

BillThor
źródło
3
Pola z wiodącymi zerami są ciągami, reprezentacjami wizualnymi o własnym znaczeniu, a nie liczbami.
Pieter B
1
+1 uznać za chmod 438 ./myfileokropne!
Ingo
2
Dlaczego nie pozwolić na 0o10składnię? Wierzę, że Python to obsługuje. Zawsze możesz w prosty sposób zapisać wartości ósemkowe, które nie powodują, że liczba nie jest już liczbą normalną. Widziałem, jak ludzie próbują używać końcowych zer w kodzie do wyrównywania i łatwej manipulacji, i gryzie się w stopę za pomocą notacji ósemkowej
Manishearth 15.01.2014
Rozumiem chęć posiadania środków do pisania wartości ósemkowych, oprócz binarnych i szesnastkowych. Rozumiem również, że interpretacja kompilatora 031jako Halloween (31 października), a nie Bożego Narodzenia (25 grudnia) może stanowić pewne ryzyko, jeśli programiści skopiują kod napisany w języku używającym tej ostatniej implementacji. Nie widzę jednak powodu, dla którego język nie mógłby osiągnąć tego, co najlepsze w obu światach, obsługując 0q31jako notację, gdy pożądana jest liczba ósemkowa, lub 0t025dla dziesiętnej podstawy, aby zezwolić na wklejanie makr z wiodącymi zerami i po prostu zabraniając wiodącym zerom bez podstawowych specyfikatorów .
supercat
@ supercat Użycie wiodącego 0 do reprezentowania ośmiokrotnych dat wstecz przynajmniej dla twojej młodości. Przypadkami, w których jest często używany, są przypadki, w których bity mają znaczenie, a interpretacja liczby jako liczby dziesiętnej jest poprawna tylko dla wartości mniejszych niż 8. Dodanie dodatkowych znaków (w tym zer wiodących na liczbach dziesiętnych) może być bardziej mylące niż pomocne . Z pewnością zapytałbym, dlaczego zapisano datę 012 031, 010 031 lub 012 025.
BillThor