Dlaczego bash myśli: 016 + 1 = 15?

60

Czy ktoś może mi wyjaśnić, dlaczego liczba z wiodącym 0 daje to zabawne zachowanie?

#!/bin/bash
NUM=016 
SUM=$((NUM + 1)) 
echo "$NUM + 1 = $SUM"

Wydrukuje:

016 + 1 = 15

DeltaLima
źródło
3
Psst: printf "%03d\n" 10jest całkowicie użyteczny w bash, aby uzyskać wiodące zero dla nazw plików i tym podobne.
Squeezy,
@Squeezy Dzięki, ale ta część już działała. Rzeczywistym problemem nie było uzyskanie nazwy pliku z wiodącym 0. Znalezienie nazwy pliku o najwyższym numerze, a następnie utworzenie kolejnej sekwencji za pomocą printf „prefix-% 03d.tif” $ SUM.
DeltaLima,
8
Zauważ, że sam mogłeś to po prostu zrobićecho $((016))
Mehrdad
2
Do Twojej wiadomości dotyczy to wielu języków programowania: C, C ++, Javascript.
Paul Draper,

Odpowiedzi:

128

Nieporozumienie polega na tym, że liczby nie oznaczają tego, czego oczekujesz.

Początkowe zero oznacza liczbę o podstawie 8. Ie 016jest taka sama jak 8#16. Jeśli chcesz zachować wiodące zero, potrzebujesz 10#016.

> num=016
> echo $((num))
14
> echo $((10#$num))
16
Hauke ​​Laging
źródło
23
Na świecie jest 10 rodzajów ludzi. Ci, którzy rozumieją binarne, ci, którzy nie, ci, którzy nie spodziewali się podstawowego 8 żartu i 5 innych rodzajów ludzi.
Jon Story
42

Dlatego:

~$ echo $((NUM))
14

jeśli liczba zaczyna się od 0, uważa się ją za wartość ósemkową, a 16 w liczbie ósemkowej to 14 w systemie dziesiętnym.

fredtantini
źródło
2
To doskonale pokazuje i wyjaśnia, dlaczego mój skrypt zastępował moje stare pliki :-(
DeltaLima