Czy 0 jest literałem dziesiętnym czy ósemkowym?

329

Zero jest zawsze równe zero, więc to nie ma znaczenia. Ale w niedawnej dyskusji z przyjacielem powiedział, że literalne ośmiokrotne są dziś prawie nieużywane. Potem przyszło mi do głowy, że właściwie prawie wszystkie liczby całkowite w moim kodzie ósemkowe, mianowicie 0.

Czy liczba 0ósemkowa jest zgodna z gramatyką C ++? Co mówi standard?

Jedyne, o czym jestem świadomy, to uprawnienia do plików unixowych.

Jakow Gałka
źródło
6
Czy to samo dotyczy Javy?
Philippe
80
+1 za zadanie całkowicie nieistotnego pytania i uzyskanie mnóstwa pozytywnych opinii :-)
Kerrek SB
64
Myślę, że sposób na natychmiastowe powtórzenie na SO nie jest głębokim pytaniem, ale osobliwym pytaniem, na które odpowiedź sprawiłaby, że jesteś maniakiem w chłodnicy wody :)
Josh
4
Wspaniałe pytanie :) Poszukałem go w specyfikacji języka Java , a w Javie jest on dziesiętny. Specyfikacja zawiera nawet następujący cytat: Zauważ, że liczby ósemkowe zawsze składają się z dwóch lub więcej cyfr; 0 jest zawsze uważane za liczbę dziesiętną - nie ma to większego znaczenia w praktyce, ponieważ cyfry 0, 00 i 0x0 oznaczają dokładnie tę samą liczbę całkowitą.
Tobias Ritzau,
14
Niemal mam ochotę opublikować odpowiedź: „Tak, 0 jest literałem dziesiętnym lub literałem ósemkowym”.
Keith Thompson

Odpowiedzi:

296

Tak, 0jest literałem ósemkowym w C ++.

Zgodnie ze standardem C ++:

2.14.2 Literały całkowite [lex.icon]

integer-literal:  
    decimal-literal integer-suffixopt  
    octal-literal integer-suffixopt  
    hexadecimal-literal integer-suffixopt  
decimal-literal:  
    nonzero-digit  
    decimal-literal digit  
octal-literal:  
    0                           <--------------------<Here>
    octal-literal octal-digit
Alok Save
źródło
39
Inną ważną kwestią jest to, że literał dziesiętny jest cyfrą niezerową, po której następuje zero lub więcej cyfr, więc nie ma dwuznaczności.
CB Bailey,
3
@MSalters: Z wersji, trzeba dodatkowo określić preferencje: Jeśli oba octal-literal i decimal-literalsą możliwe interpretacje wzorca bajtowego, pick octal-literal. Brzmienie oficjalnego standardu nie ma tego problemu.
Martin Sojka
23
@MSalters: Nadal nie można mieć literału dziesiętnego jako dowolnej liczby cyfr, musi to być pojedyncza cyfra zerowa lub niezerowa, po której następują dowolne cyfry, w przeciwnym razie każdy literał dziesiętny można interpretować jako literę dziesiętną. Widzę błąd kompilacji, obecnie: ERROR: 0 is ambiguous, could be octal zero or could be decimal zero. Consider using (1 - 1) to disambiguate.
CB Bailey
3
@MSalters W twoim przykładzie 0123 pasowałoby zarówno do literału ósemkowego, jak i dziesiętnego, ale miałoby różne znaczenia w obu kierunkach.
puszysty
5
@CharlesBailey - FTFY, 1wciąż ósemkowy; P -ERROR: 0 is ambiguous, could be octal zero or could be decimal zero. Consider using (8 - 8) to disambiguate
twalberg
44

Każda liczba całkowita z prefiksem 0jest wartością ósemkową. To znaczy: 01 to liczba ósemkowa 1, 010 to liczba ósemkowa 10, która jest dziesiętna 8, a 0 to liczba ósemkowa 0 (która jest dziesiętna i dowolna inna, 0).

Tak więc „0” jest ósemką.

To proste angielskie tłumaczenie fragmentu gramatyki w odpowiedzi @ Alsa :-)


Liczba całkowita z prefiksem nie0x jest poprzedzona prefiksem . jest wyraźnie innym przedrostkiem. Najwyraźniej są ludzie, którzy nie potrafią tego rozróżnić.00x

Zgodnie z tym samym standardem, jeśli będziemy kontynuować:

 integer-literal:
     decimal-literal integer-suffixopt
     octal-literal integer-suffixopt
     hexadecimal-literal integer-suffixopt
 decimal-literal:
     nonzero-digit                       <<<---- That's the case of no prefix.
     decimal-literal digit-separatoropt digit
 octal-literal:
     0                                    <<<---- '0' prefix defined here.
     octal-literal digit-separatoropt octal-digit <<<---- No 'x' or 'X' is
                                                          allowed here.
 hexadecimal-literal:
     0x hexadecimal-digit                 <<<---- '0x' prefix defined here
     0X hexadecimal-digit                 <<<---- And here.
     hexadecimal-literal digit-separatoropt hexadecimal-digit
littleadv
źródło
5
„Każda wartość całkowita rozpoczynająca się od„ 0 ”jest wartością ósemkową.” Nie prawda. Przykład: 0xA zaczyna się od „0” i jest liczbą całkowitą.
Nikolai Ruhe
4
0xnie jest tokenem. Literał całkowity rozpoczynający się od 0xjest pojedynczym tokenem.
Keith Thompson
4
Jakie źródło podajesz dla tej definicji? Słowo „token” jest zdefiniowane składniowo przez standardy C (N1570 6.4) i C ++ (C ++ 11 2.7 [lex.token]). 0xnie kwalifikuje się. (Przynajmniej w C jest to liczba wstępnego przetwarzania (N1570 6.4.8), jeśli nie jest częścią stałej szesnastkowej, ale to nie jest token.)
Keith Thompson
11
Omawiamy składnię stałych całkowitych / literałów zgodnie ze standardami C i C ++ . W jaki sposób definicja „tokena” w normach nie jest najbardziej odpowiednia do użycia w tym kontekście? Twoja obraźliwa protekcjonalność jest nieodpowiednia. A jeśli uważasz, że jestem prześladowcą za wskazanie czegoś, co moim zdaniem jest błędem technicznym w Twojej odpowiedzi, sugeruję, abyś ponownie rozważył znaczenie tego słowa. (Nigdy nie odpowiedziałeś na moje pytanie dotyczące źródła twojej definicji.)
Keith Thompson
4
Jeśli ktoś jest ciekawy, stwierdzenie, że „ token jest ciągiem jednego lub więcej znaków, które są znaczące jako grupa ”, wydaje się pochodzić z tego artykułu z Wikipedii .
Keith Thompson
-2

Najwyraźniej wszystkie literały całkowite zaczynające się od zera są w rzeczywistości ósemkowe. Oznacza to, że zawiera również 0. To niewiele robi, ponieważ zero wynosi zero. Ale nie wiedząc o tym, może cię skrzywdzić.

Zrozumiałem to, kiedy próbowałem napisać program do konwersji liczb binarnych na dane dziesiętne i szesnastkowe. Za każdym razem, gdy podawałem liczbę zaczynającą się od zera, otrzymywałem niewłaściwe dane wyjściowe (na przykład 012 = 10, a nie 12).

Dobrze jest znać te informacje, aby nie popełnić tego samego błędu.

MCG
źródło
7
Literały całkowite zaczynające się od zera, ale bez „x” po zera.
luiscubal
5
Twierdzenie „tak” bez dowodu również nie jest odpowiedzią.
Wyścigi lekkości na orbicie
1
Zgodnie z tą logiką 09 jest liczbą ósemkową.
0xc0de,
3
@ 0xc0de: Nie, 09nie jest liczbą ósemkową , ponieważ wcale nie jest liczbą; nie pasuje do składni żadnego rodzaju literału całkowitego.
Keith Thompson,
7
Jestem całkiem pewien, że @ 0xc0de wie, że 09to nie jest liczba ósemkowa. Co zostało powiedziane było: „ Według tej logiki , 09jest liczba ósemkowa.” Wynika z tego, że skoro 09to nie jest numer ósemkowy, logika musi być nie tak.
TRiG