Pourquoi bash pense-t-il: 016 + 1 = 15?

60

Quelqu'un peut-il m'expliquer pourquoi un nombre avec un 0 mène à ce comportement amusant?

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

Imprimera:

016 + 1 = 15

DeltaLima
la source
3
Psst: printf "%03d\n" 10est complètement utilisable dans bash pour obtenir un zéro non significatif pour les noms de fichiers et autres.
Squeezy
@Squeezy Merci, mais cette partie fonctionnait déjà. Le problème réel n’était pas d’obtenir un nom de fichier avec un 0 initial. C’était de rechercher le nom de fichier portant le numéro le plus élevé, puis de créer le suivant dans l’ordre en utilisant printf "prefix-% 03d.tif" $ SUM.
DeltaLima
8
Notez que vous auriez pu comprendre cela vous-même en faisant celaecho $((016))
Mehrdad
2
Pour votre information, cela est vrai dans de nombreux langages de programmation: C, C ++, Javascript.
Paul Draper

Réponses:

128

Le malentendu est que les chiffres ne veulent pas dire ce que vous attendez.

Un zéro au début indique un nombre de base 8. Ce 016est le même que 8#16. Si vous voulez conserver le zéro non significatif, il vous faut 10#016.

> num=016
> echo $((num))
14
> echo $((10#$num))
16
Hauke ​​Laging
la source
23
Il y a 10 types de personnes dans le monde. Ceux qui comprennent le binaire, ceux qui ne comprennent pas, ceux qui ne s'attendaient pas à une blague de base 8, et 5 autres types de personnes.
Jon Story
42

Parce que:

~$ echo $((NUM))
14

si le nombre commence par 0, il est considéré comme une valeur octale et 16 en octal est 14 en décimal.

fredtantini
la source
2
Cela fait sens et explique pourquoi mon script
remplaçait