Pourquoi les ordinateurs comptent-ils à partir de zéro?


55

Les ordinateurs totalisent traditionnellement les valeurs numériques à partir de zéro. Par exemple, les tableaux dans les langages de programmation en langage C commencent à partir de l'index zéro.

Quelles sont les raisons historiques à cela et quels sont les avantages pratiques de compter à partir de zéro?

Remarque: cette question demande des réponses techniques bien expliquées, pas seulement des opinions, et vise à couvrir les ordinateurs en général plutôt que la programmation. Cette question développe la question des programmeurs "Pourquoi les structures / tableaux sont-ils basés sur zéro?" .



9
Il y a eu plus de quelques exemples de langages informatiques qui utilisaient des tableaux à origine unique.
Daniel R Hicks

23
Pourquoi les humains ne comptent-ils pas à partir de 0?
Sans titre

47
Woah, woah, personne ne compte de zéro, nous indice de zéro. Personne ne dit l'élément "zeroth". Nous disons le "premier" élément à l' indice 0. Considérez l'indice comme la distance qui le sépare d'un élément à la première position. Eh bien, le premier élément est à la première position, de sorte qu'il n'est pas du tout décalé. Son index est donc 0. Le deuxième élément est précédé d'un élément, il est donc décalé d'un élément et se trouve à l'index 1
mowwwalker le

14
@Ramhound Non, ça ne l'est pas. L'indexation basée sur zéro n'a aucun lien avec l'utilisation de binaire.
Peter Olson

Réponses:


88

Compter les tableaux à partir de 0 simplifie le calcul de l'adresse mémoire de chaque élément.

Si un tableau est stocké à une position donnée en mémoire (on l’appelle adresse), la position de chaque élément peut être calculée comme suit:

element(n) = address + n * size_of_the_element

Si vous considérez le premier élément comme le premier, le calcul devient

element(n) = address + (n-1) * size_of_the_element

Pas très différent mais cela ajoute une soustraction inutile pour chaque accès.

Modifier

  • L'utilisation de l'index de tableau en tant que décalage n'est pas une exigence, mais simplement une habitude. Le décalage du premier élément peut être masqué par le système et pris en compte lors de l'allocation et du référencement d'un élément.

  • Dijkstra a publié un article "Pourquoi la numérotation devrait commencer à zéro" ( pdf ) où il explique pourquoi commencer par 0 est un meilleur choix. Partir de zéro permet une meilleure représentation des plages.


8
+1 pour la réponse correcte. Notez que l'indexation basée sur 0 n'est qu'une convention (très courante) du langage utilisé; ce n'est pas universel. Par exemple, Lua utilise l'indexation basée sur 1 . La "soustraction inutile" était peut-être le raisonnement qui sous-tendait l'indexation basée sur le zéro dans le passé, mais maintenant, la plupart des langages l'utilisent simplement parce que c'est ce à quoi tout le monde est déjà habitué (en grande partie grâce à C) , et il n'y a aucune raison impérieuse de changer cela. convention.
BlueRaja - Danny Pflughoeft

2
Cela n'a aucun sens. La position de chaque élément peut toujours être calculée tant address + n * size_of_elementque "l'adresse" est l'adresse de l'élément zéro. Cela fonctionne parfaitement, que l'élément zeroth existe ou non en tant qu'élément du tableau. La question est de savoir pourquoi l'élément zeroth existe et non pourquoi nous stockons les adresses en tant qu'adresse de l'élément (éventuellement notionnel) zeroth. (Ce à quoi cela répond.)
David Schwartz

3
@DavidSchwartz Prenons un ancien langage comme C. Si vous allouez de la mémoire, vous obtenez une adresse à laquelle la mémoire commence. Si un compilateur voit quelque chose comme v[n]cela, il doit calculer l'adresse de l'expression. Si les index commencent à 0, le calcul est v + x * size. Si à 1 le calcul est v + (x-1) * taille. Par exemple, v [1] correspondra à v + (1-1) * taille qui est v.
Matteo

4
@David: En C (le langage qui a vraiment popularisé l'indexation à base de 0) , les tableaux et les pointeurs sont largement interchangeables; il est donc important pour un certain nombre de raisons de *arrayse référer au premier élément. Un exemple: si nous avons arraypointé sur l’emplacement mémoire avant le premier élément, la conversion en un tableau de type différent serait gênante, par exemple. la position du deuxième octet dans un tableau de ints dépendrait de la taille du mot; sur une machine 32 bits, ce serait à ((char*)intArray + 5)!!
BlueRaja - Danny Pflughoeft

3
Non, le problème est de savoir si le tableau contient un élément zeroth. Parce que vous voyez, il y a aussi une mise à l'échelle. Si j'ai un tableau d'objets de 8 octets et que je le superpose avec un tableau d'octets, quel est l'indice d'octet de l'objet [42]? Pourquoi c'est simple: 42 * 8. Le problème de 1 est que ce décalage de 1 est de 1 octet lorsque je regarde le tableau d'octets, et de 8 octets lorsque je regarde le tableau superposé de 8 octets.
Kaz

38

Alors que les principes ci-dessous s'appliquent à la base décimale ainsi qu'à toute autre base, Compter à partir de 0 dans les ordinateurs peut être facilement compris naturellement à partir du système binaire à chiffres fixes qui représente les nombres utilisés dans les ordinateurs. Si vous avez 8 bits, il y a 256 combinaisons possibles de 1 et de 0 pouvant être exprimées. Vous pouvez utiliser ces 8 bits pour exprimer les nombres 1-256, mais cela laisserait 0, ce qui est utile en mathématiques en tant que nombre en soi, ils sont donc utilisés pour exprimer les nombres 0-255.

Cela crée déjà un précédent d'ordre naturel commençant de 0 (tous les 0 dans la représentation binaire) à 255 (tous les 1 dans un nombre de 8 bits). Considérer le système de représentation des nombres, commençant à 0, a du sens car 0 est le "premier" numéro du système, donc 1 est le "second" nombre, et ainsi de suite.

Une autre raison pour laquelle il est si pratique de partir de 0 dans les ordinateurs est due au concept de compensation. Un décalage est un nombre représentant la distance d'un emplacement en mémoire, sur un disque dur ou sur tout autre support "adressable". Dans les ordinateurs, pratiquement toutes les données sont stockées de manière linéaire, ce qui signifie qu'il existe un ordre dans les données, un premier octet, un deuxième octet, etc. Il est pratique d'exprimer la localisation de "zones" de données via un décalage. Quel est le premier octet dans un bloc de données? Il se trouve à l'offset "0", ce qui signifie qu'il se trouve 0 octet après le premier octet du bloc de données. Bien qu'il soit possible que "1" désigne le premier octet, cela crée des complications dans la représentation des données pour plusieurs raisons:

  • En excluant 0 de l’adressage des données, vous réduisez le nombre de choses que vous pouvez traiter avec un nombre de 8 bits de un.
  • Pour calculer le décalage, nécessaire au niveau matériel de l'accès aux données, vous devez à un moment soustraire un de la numérotation, ce qui introduit une complexité.
  • Les pointeurs sur un bloc de données pointent toujours sur le premier bloc. L'arithmétique est donc simple lorsque vous partez de 0. (Le premier octet du premier bloc du premier groupe de données est 0 + 0 + 0 lorsque vous partez de 0. , il est 1 + 1 + 1 - 1 -1 lorsque vous commencez à partir de 1.) L'arithmétique de ceci lorsque vous commencez à 1 avec des infrastructures de données imbriquées comme cet exemple peut être déroutant.

31
N'a rien à voir avec la représentation binaire. Les nombres binaires et décimaux commencent à 0.
Matteo

2
Si vous commencez à compter à partir de 0, vous ne réduirez pas le nombre d'adresses que vous pourriez (en théorie) aller de 1 à 257.
Matteo

6
@ Matteo pas dans un seul octet, vous ne pourriez pas
Arrêtez de nuire Monica

8
@Dougvj Le comptage basé sur zéro n'a absolument rien à voir avec le binaire. Vous voulez utiliser chaque chiffre dans une représentation à chiffre fixe, ce qui est une préoccupation, que vous utilisiez la base 2, la base 10 ou la base 23517.
Peter Olson

2
-1 Cela n'a absolument rien à voir avec la représentation binaire.
BlueRaja - Danny Pflughoeft

26

Jamais pensé qu'une occasion pour un philosophe de fauteuil comme moi viendrait sur Superuser. Il y a une idée fausse fondamentale à l'esprit ici, parce que les non-philosophes ont tendance à ignorer les détails les plus infimes. En bref: les ordinateurs ne comptent pas à partir de zéro, mais la dénomination des positions commence à zéro.

Il n’ya rien de déroutant dans cette incohérence perçue entre les techniques de comptage informatique et humaine (toutes). Décomposons la question.

Pourquoi les ordinateurs comptent-ils à partir de zéro?

  • Ils ne comptent pas à partir de zéro

Les ordinateurs calculent les valeurs à partir de zéro. Par exemple, les tableaux en C.

  • L' indice (indicateur de position, pointage) commence à zéro. Le nombre d'éléments dans un tableau où il y a un seul élément à l'indice zéro est un

Zéro est pratique pour représenter un vide de quelque chose ou le point central d'une échelle. Ce n’est pas pratique de compter quoi que ce soit, car il est impossible par définition de zéro.

Dans le même sens que le point central d'une échelle, le zéro peut être utilisé pour représenter le bord même (début absolu) d'une collection. La question n'a pas de sens car elle est incohérente entre les "valeurs de comptage" et "compter à partir de zéro".

Alors oui, les ordinateurs sont à partir de zéro, mais ils comptent à partir de un. Les deux mots ont un sens différent.

tal·ly [tal-ee]

nom

  1. un compte ou compte; un enregistrement de débit et de crédit, du score d'un jeu ou similaire.
  2. tout ce qui contient un score ou un compte ..
  3. un nombre ou un groupe d'éléments enregistrés.

compter [kount]

verbe (utilisé avec objet)

  1. vérifier (les unités ou groupes distincts d'une collection) un par un pour déterminer le nombre total; additionner; énumérer: il compta ses billets et découvrit qu'il en avait dix.
  2. à compter; calculer; calculer.
  3. pour lister ou nommer les chiffres jusqu'à: Fermez les yeux et comptez dix.

(dictionary.com)


Les raisons pratiques sont correctement décrites par Dougvj, je n’ai rien à ajouter. Si seulement nous pouvions avoir un professeur de CS (des années 60) pour donner un compte rendu historique ...


En fait, comment savez-vous où l'ordinateur commence quoi que ce soit? Tout ce que vous savez, c'est que lorsque vous l'utilisez, vous lui dites de recommencer à zéro.
Daniel R Hicks

Je parle ici des définitions des concepts et de la logique, pas du fonctionnement des ordinateurs en tant que tel. Je connais un peu les débuts de l'informatique, car j'ai suivi des cours de formation continue.
рослав Рахматуллин

1
Pour être complètement pédant, vous comparez un verbe avec un nom. Je pense que "tally" et "count" sont vraiment synonymes, et les deux peuvent être utilisés comme verbe ou comme nom.
Brian

1
@Brian Une observation juste et mon intention est d’illustrer (de manière pédante) que la confusion provient d’une interprétation erronée des termes. Il n'y a pas vraiment de différence entre "le 1er élément" et "l'élément en position 0". Ils sont tous deux élément un. Le premier , pas " zeroth ". Compter à partir de zéro, ça n'existe pas . L'énumération commence à un par définition, alors que l'adressage peut être a-> 1, b-> 2. c-> 3 ou 0-> 1, 1-> 2, 2-> 3. L'exemple le plus courant de "compter à partir de zéro" peut être trouvé dans les livres de mathématiques du collège sous la forme de {x₀, x₁, x₂} - mais l'indice est un indice .

1
C'est juste que les concepteurs ont en fait erré un peu avant de s'installer sur le schéma actuel. Ce qui semble "évident" maintenant ne l'était pas. Et probablement un schéma quelque peu différent aurait pu être choisi et semblerait maintenant plus "évident" que ce que nous avons.
Daniel R Hicks

12

Je pense que cela a déjà été couvert par "le professeur Edsger W. Dijkstra " - chercheur Burroughs dans une lettre du 11 août 1982: cf EWD831

Intitulé: Pourquoi la numérotation devrait commencer à zéro . "Y a-t-il des raisons de préférer une convention à l'autre? Oui, il y a ..."

Notez également que Dijkstra faisait partie de l' équipe de conception d' ALGOL 68 jusqu'à la fin de 1968. Algol68 autorise les tableaux à partir de 0, 1 ou tout nombre que le programmeur juge approprié pour l'algorithme. cf ( "The Making of Algol 68" raconte '"Pouvez-vous définir des tableaux triangulaires?", interrompit quelqu'un (Tony Hoare?). "Non seulement triangulaire, mais même elliptique" a répondu Aad et a montré comment. "

En particulier, dans Algol68, lorsque les tableaux (et les matrices) sont coupés en tranches, ils obtiennent un indice @ 1; il existe donc un biais en faveur des tableaux [1: ...]. Mais la " 1ère " borne inférieure peut être déplacée pour commencer à la "0 ème " position en spécifiant "@ 0", par exemple le vecteur x [4: 99 @ 2], la matrice y [4: 99 @ 1,4: 99 @ 0]. De même , il y a un défaut / biais de de 1 do ~ od boucles (sauf si " de 0" est explicitement dit), et de 1 pour l'entier cas i dans ~, ~, ~ ESAC et $ c (~, ~, ~ ) $ clauses de choix .

Il semble que les commentaires de Dijkstra au sujet du Mars 1968 Projet de rapport ( MR93 ) et ses insistances provoquèrent ce qui est sans doute une pré-usenet guerre de flamme : « il y a des écrits qui sont aimables , bien que agrammatical, et il y a d' autres écrits qui sont extrêmement grammaticales, mais sont dégoûtant. C’est quelque chose que je ne peux pas expliquer aux personnes superficielles. " EWD230

Le rapport final d'Algol 68 (FR) a été publié le 20 décembre 1968; il a suscité de l'opposition à la réunion de Munich, puis a été adopté par le groupe de travail. Par la suite, le rapport a été approuvé par l'Assemblée générale du PIPI de l'UNESCO pour publication.

Vers le 23 décembre 1968 (?), Dijkstra, Duncan, Garwick, Hoare , Randell , Seegmuller, Turski, Woodger et Garwick ont ​​signé l’ AB31.1.1.1 "Minority Report", page 7 (publiée en 1970).


10

L'analogie de distance que quelqu'un d'autre a évoquée se prête à une illustration très pratique:

"A quelle distance se trouve ta maison de la station-service la plus proche?"

"1 mile."

"Vous habitez à la station d'essence?"

"Non, si j'habitais à la station d'essence, ce serait 0 miles"

"Pourquoi comptez-vous à partir de zéro au lieu d'un?"

Un autre bon exemple serait les anniversaires - nous ne disons pas que quelqu'un a un an le jour de sa naissance, nous disons que c'est un an plus tard.

Nous disons que les années bissextiles ou les élections présidentielles américaines ont lieu tous les quatre ans, même si vous en comptez une: les années 2000 , 2001, 2002, 2003 et 2004 sont de cinq ans. (Incidemment, les Romains ont tout gâché pendant un moment et avaient des années bissextiles trop rapprochées)

Ce que je veux dire, c'est que nous "comptons" à partir de zéro tout le temps dans le monde réel - "Combien de positions après [début du tableau] est l'élément que vous voulez" se trouve simplement être la question à laquelle vous répondez avec un compte à partir de zéro dans de nombreux programmes informatiques. Vous ne diriez pas que le premier élément est une position après le début, n'est-ce pas? Il est le début.


1
Vos calculs concernant les élections sont décalés d'un an. Votre exemple contient 2 années d’élection dans une période de 5 ans; l'illustration correcte serait que 4 ans passent d'une élection à l'autre, c'est-à-dire 2000 -> 2001 (une période d'un an), 2001 -> 2002, 2002 -> 2003, 2003 -> 2004.
Jimmy le

1
Ce @Jimmy était mon point de - si les gens « d'un compte » dans le sens qu'ils veulent des ordinateurs à, ils compterait 2000 comme un lieu de zéro. C'est d'ailleurs ainsi que les anciens Romains l'ont réellement fait (et décriraient en effet un cycle comme "2000, 2004, 2008" comme un cycle de cinq ans).
Random832

2
Votre exemple d'anniversaire n'est pas universellement vrai. Par exemple, en Corée du Sud, la première année de vie compte pour une année au lieu de zéro .
BennyMcBenBen

6

Comme déjà dit par d'autres ordinateurs, les ordinateurs ne comptent pas à partir de zéro .

Certaines langues indexent à partir de 0. L'indexation à partir de 0 présente deux avantages principaux:

  1. Il se convertit naturellement en assemblage car il peut être interprété comme un décalage entre un pointeur et la première position.

  2. Vous n'obtenez pas d'étrangeté quand vous voulez des négatifs. Combien d'années entre 1BC et 1AD? Aucun. Car bien que la Colombie-Britannique ait effectivement des dates négatives, il n’ya pas d’année zéro. S'il y avait eu 0AD, il n'y aurait pas de problème ici. Vous voyez le même problème partout dans la science où les gens ont naïvement défini le premier élément d'un ensemble comme +1.


Oui, et toute la stupidité d'attendre jusqu'en 2001 pour le nouveau millénaire. Cela confond exactement ces personnes qui "ne reçoivent pas" non plus des tableaux à base zéro quand ils se mêlent de la programmation. :)
Kaz

3
De plus, si "1 mile" signifie "ici", alors puisqu'un mile fait 1760 pieds, cela signifie que "1760 pieds" signifie aussi "ici", n'est-ce pas? Faux, "1 pied" signifie ici, oups! Dans cette stupidité basée sur "ici-bas", c'est un pied, un pouce, un centimètre, etc.
Kaz

1
@kaz où pieds => verges. 1760 yards in mile.
Brad

3

Le décompte commence naturellement à zéro

Voici l'algorithme pour compter les pommes dans un panier:

count := 0

for each apple in basket
   count := count + 1

Après l'exécution de ce qui précède, countdétient le nombre de pommes. Il peut être nul, car les paniers peuvent être vides.

Si vous n'utilisez pas votre carte de crédit pendant un mois entier, recevez-vous une facture d'un dollar? Ou 1 centime?

Lorsque vous réinitialisez le compteur kilométrique sur le compteur kilométrique de votre voiture, passe-t-il à 0001 ou 0000?

Les tableaux peuvent fournir plusieurs vues des mêmes données

Prenons un tableau de structures 32 bits d, chacune composée de mots de 16 bits w. Chaque mot est composé de deux octets de 8 bits b. Sous zéro indexation, la superposition semble très pratique:

d: |   0   |   1   |
w: | 0 | 1 | 2 | 3 |
b: |0|1|2|3|4|5|6|7|

L'objet d[1]de 32 bits à l'adresse du mot w[2]qui est facilement calculé en multipliant l'indice par 2, qui est le rapport entre les tailles des objets de 32 et 16 bits. De plus, dans l'adressage d'octet, c'est le cas b[4].

Cela fonctionne parce que zéro est égal à zéro, dans chaque unité de mesure: octet, mot, mot double, etc.

Regardez le diagramme ci-dessus: cela ressemble beaucoup à une règle, où les conversions d'unités sont intuitives.

Avec une indexation basée, il casse:

d: |   1   |   2   |
w: | 1 | 2 | 3 | 4 |
b: |1|2|3|4|5|6|7|8|

Maintenant, nous ne pouvons pas simplement multiplier l' dindex par 2 pour obtenir l' windex, ou par 4 pour obtenir l' bindex. La conversion entre les unités devient maladroite. Par exemple, pour aller de d[2]à b[4], nous devons calculer ((2 - 1) * 4) + 1 = 5.

Nous devons soustraire ce biais 1 embêtant dans les dunités, puis procéder à la mise à l'échelle dans le système de coordonnées naturel à base de zéro, puis rajouter le 1 embêtant en bunités. Notez que ce n'est pas le même 1! Nous soustrayons une double largeur de mot, mais ajoutons ensuite une largeur d'un octet .

La conversion entre différentes vues des données devient quelque chose comme la conversion Celsius-Fahrenheit.

Ceux qui disent que les tableaux à base unique sont faciles à traiter au niveau de la mise en œuvre, car il n’ya qu’une simple soustraction de 1 se leurrent, et vous. Cela n’est vrai que si nous ne faisons aucun calcul de mise à l’échelle entre différents types de données. De tels calculs sont effectués dans tout programme disposant d'une vue flexible sur les données (par exemple, un tableau multidimensionnel auquel on accède également en tant qu'un graphique unidimensionnel) ou manipulant le stockage: par exemple, un allocateur de mémoire, un système de fichiers ou une bibliothèque de mémoires vidéo.

Minimiser les chiffres

Dans n'importe quelle base, si nous voulons utiliser le moins de chiffres possible pour implémenter une plage de valeurs qui est une puissance de la base, nous devons partir de zéro. Par exemple, en base dix, trois chiffres suffisent pour nous donner mille valeurs distinctes de 0 à 999. Si nous partons de 1, nous débordons d’une seule valeur et nous avons besoin de quatre chiffres.

Ceci est important dans les ordinateurs, car le nombre de chiffres en binaire se traduit par des lignes d'adresse matérielles. Par exemple, une puce ROM contenant 256 mots peut être adressée de 0 à 255, ce qui nécessite 8 bits: 00000000 à 11111111. Si elle est adressée de 1 à 256, alors 9 bits sont nécessaires. Nous devons gaspiller une trace d'adresse supplémentaire dans la carte de circuit imprimé ou le circuit intégré. Donc, ce qui se passerait éventuellement dans la pratique serait que 0 serait simplement appelé1 au niveau de l'API logicielle pour accéder à cette puce. Une demande du mot 1 mettrait en réalité 00000000 sur le bus d’adresse à 8 bits. Sinon, une demande pour 1 se traduirait par l'adresse 00000001, comme prévu, mais une demande pour 256 serait mappée sur l'adresse 8 bits inutilisée 00000000 plutôt que sur l'adresse 9 bits 100000000. Ces deux kludges déchirants sont vraiment des solutions en rechercher un problème et sont entièrement évités en utilisant systématiquement 0 à 255, tant dans le matériel que dans le logiciel, ainsi que dans toutes les interfaces utilisateur et la documentation.

Les déplacements uniques sont fondamentalement stupides

Prenons l'exemple de la théorie de la musique occidentale. Nous avons des gammes diatoniques à sept notes, mais nous appelons l'espace qu'elles couvrent une octave ! L'inversion des intervalles suit alors la règle de neuf : par exemple, l'inversion d'un tiers est un sixième (soustrayez trois à neuf). Donc, trois nombres différents sont en jeu pour quelque chose d'aussi simple: sept (notes dans une échelle), huit (octave) et neuf (soustraire de pour inverser).

Si sept notes faisaient un septave ou un heptave et que les intervalles étaient basés sur zéro, nous soustrayions alors de sept pour inverser. Tout basé sur sept.

En outre, les intervalles pourraient être facilement empilés. Dans le système actuel, si nous sautons d'un cinquième, puis d'un quatrième, puis d'un tiers, nous ne pouvons pas simplement les ajouter. L'intervalle résultant est deux moins. Ce n'est pas un douzième, mais en réalité un dixième! A chaque étape, il faut en soustraire un. Monter d'un cinquième et ensuite d'un quart n'est pas un neuvième, mais seulement une octave.

Dans un système de musique conçu avec soin, nous pourrions simplement ajouter des intervalles pour déterminer les sauts qui en résultent. Une séquence de notes commençant et se terminant sur la même note aurait alors une propriété similaire à la loi de tension autour d'un circuit: tous les intervalles s'ajouteraient à zéro.

La théorie musicale et l'écriture est très dépassée. La majeure partie n’a pas changé depuis la composition des jours avec des plumes à la lumière d’une bougie.

Les systèmes à base unique confondent les mêmes personnes qui ne peuvent pas gérer les tableaux à base zéro

À la fin de l’an 2000, beaucoup de gens n’avaient pas compris pourquoi le nouveau millénaire n’avait pas commencé. Ceux qui ont souligné que cela ne commencerait pas avant 2001 étaient considérés comme des fous et des dweebs. Après tout, vous avez 20 ans quand vous aurez 20 ans, n'est-ce pas? Pas à 21 ans. Si vous pensiez que le millénaire a commencé le 1er janvier 2000, vous n’avez pas le droit de vous plaindre de tableaux à base zéro dans aucun langage de programmation. Ils fonctionnent exactement comme vous le souhaitez. (Mais, oui, les partisans des déplacements uniques et des réseaux sont des partisans et des fêtards. Les siècles devraient commencer sur XX00 ans et les millénaires sur X000 ans.)

Les calendriers sont stupides, mais au moins l'heure de la journée est à zéro

Chaque nouvelle minute de votre montre commence par: 00 secondes. Chaque nouvelle heure commence par 00:00 minutes et secondes. Et, au moins sur une horloge de 24 heures, le jour se termine lorsque minuit sonne et que 11:59:59 s’incrémente à 00:00:00.

Ainsi, si vous voulez calculer les secondes à partir de minuit pour une heure comme 13:53:04, il vous suffit d'évaluer 13 * 3600 + 53 * 60 + 4. Pas d' 1additions ni de soustractions insipides .

Clôture de clôture sur le MIDI

D'accord, qu'en est-il des musiciens, même supposés techniques?

MIDI! Il utilise la numérotation à base zéro pour les programmes et les canaux dans la représentation câblée des messages, mais Gear l’affiche sous la forme 1! Par exemple, les programmes 0 à 127 sont appelés 1 à 128 sur la plupart des engins, mais certains les appellent de 0 à 127 ou donnent même le choix à l'utilisateur.

Les programmes 71 à 80 sont considérés comme une "banque" de dix. C'est ce qui est écrit sur ma pédale MIDI, par exemple. Les commutateurs au pied sont étiquetés de 1 à 10 et, si je suis dans la septième banque, ils sélectionnent les programmes 71 à 80. Cependant, certains périphériques ou logiciels informatiques affichent les numéros de programme 1-128 de 0 à 127, voire donnent à l'utilisateur une choix! Qu'est-ce qui est pire: des systèmes à base unique ou le chaos créé en utilisant à la fois les systèmes un et zéro?

Les numéros de canal MIDI sont appelés de 1 à 16, mais sont représentés par 0 à 15 binaires. Comme par dépit pour la présentation à base unique, certains équipements utilisent un dispswitch pour configurer un numéro de canal et, souvent, ces commutateurs utilisent simplement le code binaire basé sur zéro. Donc, si vous voulez le canal 3, vous devez le basculer sur 0010 (binaire 2).


1

Si je me souviens bien de ma classe de concepts de langage de programmation, les langues étant indexées par 0 et les autres par indexant des raisons historiques. Algol-68, le grand-père des langages de programmation, était en fait indexé sur 1, de même que le Fortran et quelques autres langages "professionnels" tels que COBOL. Cependant, dans certaines de ces langues, vous pouvez spécifier explicitement quel serait votre index de départ. Il y a un tableau intéressant de ceci ici .

Dans les " Ye Olde Days ", les mathématiciens, scientifiques et autres "universitaires" utilisaient généralement des langues indexées par 0, tandis que les utilisateurs de langues telles que COBOL trouvaient qu'il était inutile de commencer à compter à 0, ce qui était donc plus logique. pour commencer à 1 (cela semblait moins déroutant).

Maintenant, si votre question porte sur les raisons pour lesquelles un ordinateur ( pas un langage ) commence naturellement à compter à partir de zéro ... eh bien, c’est inhérent au binaire: ex: 0000= zéro 0001= un ... et ainsi de suite en avant ...


4
N'a rien à voir avec la représentation binaire. Les nombres binaires et décimaux commencent à 0 (comme vous le montrez dans votre exemple).
Matteo

Eh bien, cela a autre chose à voir avec le binaire. Avec quatre bits, 0000 à 1111, vous pouvez adresser une banque de mémoire de 16 mots. Si vous le faites sur une base, vous avez besoin de cinq lignes d'adresse pour représenter 0001 à 10 000. Sinon, vous faites ce que le MIDI fait, par exemple, avec les numéros de canal: 0000 est utilisé en interne, mais les interfaces utilisateur affichent 1! Si le matériel était basé sur des décimales, le problème serait le même. Trois chiffres vous donnent mille adresses si vous partez de zéro, mais si vous partez de 1, vous avez besoin de quatre chiffres.
Kaz

1

Le numéro 0 peut désigner différentes significations: valeur numérique, ordinale, adresse mémoire, etc.

"Index zéro" ne signifie pas que les programmeurs comptent à partir de zéro. Il désigne la première place d'un bloc de mémoire alloué et «0» en est l'adresse.

En C, une boucle dans un tableau pourrait s’écrire comme suit:

int arr[N];
for (i=0; arr[N]; ++i) {
...
}

Le même travail peut être fait en C #:

Object[] arr;

for (Object o in arr) {
...
}

Je pense qu'il n'y a pas de comptage dans les deux exemples.


1

Commencer à zéro est pratique pour décrire une distance par rapport à quelque chose. Donc dans ce tableau:

[4,9,25,49]

la distance entre le début de la matrice et le 25 est 2 - vous devez sauter deux étapes pour y arriver. La distance au 4 est zéro - vous n'avez pas besoin de bouger du tout.

C'est pratique de penser ainsi en additionnant des distances (ou des index): j'avance d'un pas, puis de zéro, puis de deux, où suis-je? Je suis à l'indice 1 + 0 + 2 = 3. En sautant trois étapes, je me retrouve à 49 dans le tableau ci-dessus.


Compter les étages dans un bâtiment devrait vraiment être la même chose (même si nous ne le faisons pas de cette façon aux États-Unis). Le niveau du sol devrait être égal à zéro car vous n’avez pas monté ou baissé; c'est une position de départ.

Pourtant, le rez-de-chaussée est le premier où vous venez. Vous commencez à compter lorsque vous entrez dans le bâtiment, au rez-de-chaussée, et vous ajoutez au fur et à mesure. Partir de zéro a du sens si vous considérez "dans un bâtiment" comme étant l'état par défaut / normal / naturel, ce qui est un commentaire intéressant sur la société urbaine. Zéro pour le niveau du sol a également beaucoup de sens si plusieurs sous-niveaux sont communs.

1

Rappelez-vous comment les nombres sont représentés dans un ordinateur. Prenons une bytevariable. 0 est représenté par 00000000 1 en binaire. 1 est 00000001. 2 est 00000010. Et ainsi de suite.

Notez que le nombre le plus bas bytepouvant être stocké est 0. Si nous commençons les indices de tableau avec 1, le système serait inefficace, car nous avons maintenant un tableau de longueur 255 au lieu de 256. Étant donné que les nombres d'un programme C sont compilés en nombres binaires ( ints généralement, unsigned ints dans les indices de tableau), il semble naturel d’utiliser 0 comme indice de départ car il est plus efficace.

De plus, en C ++, a[p]se déplie en *(a+p*n), où nest la taille du type de données. En d'autres termes, a[p]signifie "Donne-moi l'élément à l'index a+n*p". Si nous commençons pavec 1, alors nous aurions une portion vide / non utilisée à l’index a.

1. Bien sûr, la question évidente "pourquoi" se pose. Pourquoi ne pas définir 00000000 à 1? Simple: l'addition binaire (effectuée par cascades d'unités d'additionneur complètes) est simple dans le matériel lorsque 00000000 est égal à 0. L'addition binaire fait partie intégrante de toutes les opérations arithmétiques. Si vous faites en sorte qu'il représente 1, vous devrez soit demander au compilateur de soustraire 1 de tous les nombres, soit raccorder les circuits d'additionneur de façon à soustraire un premier des additifs et le redéfinir sur la somme. (notez que vous ne pouvez pas simplement en soustraire un plus tard, car le bit de retenue peut être impliqué)


@sec parce que cela devient absurde au niveau matériel (voir edit)
Manishearth

1

Modulo

Une bonne chose que les bonnes réponses existantes ne mentionnent pas encore: l’indexation basée sur zéro fonctionne bien avec les opérations modulo, qui peuvent donc être combinées pour former une liste cyclique. Pensez par exemple à quelque chose comme

color = colors[i % colors.length]

ce qui pourrait donner à chaque objet (indexé par i) une couleur différente de la liste colors, jusqu'à ce que toutes les couleurs aient été utilisées, point auquel il recommencerait depuis le début. Exprimer la même chose dans l'indexation à une base est assez maladroit:

color = colors[(i - 1) % colors.length + 1]

Les opérations modulo automatiques imposées par l'arithmétique binaire non signée de taille fixe avec bouclage constituent un autre exemple de la raison pour laquelle cela a du sens.

S'adresse à la fois

Une autre chose à considérer est le fait qu'il est assez facile de ne pas utiliser le premier élément d'un tableau basé sur zéro. (Cela ne tient pas compte de l' foreachitération de style et des constructions de langage similaires qui traitent le tableau dans son ensemble.) De nombreux programmeurs, y compris moi-même, pourraient se sentir un peu gênés par l'espace gaspillé, mais dans la plupart des situations, la quantité est si minime que ces inquiétudes sont non fondés. En revanche, si les langages utilisent une indexation à base unique, il n’existe aucun moyen de simuler un élément à l’indice zéro sans beaucoup de code. Donc, étant donné que dans certaines situations, l’indexation basée sur zéro est préférable à l’unique, choisir zéro partout comme base est l’approche la plus flexible, par opposition à une approche unique, et elle est également plus cohérente que les positions de départ configurables.


0

Les systèmes informatiques utilisent à la fois des nombres naturels (en partant de 0) et des nombres entiers (en partant de 1). Les gens comptent les choses en nombres entiers, ce qui les rend intuitives pour les listes de numérotation, et de nombreux langages de programmation en tirent parti: BASIC, COBOL, Fortran, Lua et Pascal comptent tous à partir de 1. Ces langages ciblent des niches comme le traitement de données, l'analyse numérique, et l'enseignement, où des listes simples et intuitives sont un avantage.

Les nombres entiers deviennent difficiles lorsque vous commencez à analyser et à manipuler la structure des données, au lieu de tout traiter dans l'ordre. Lorsque vous devez vous référer à des séquences dans une formule ou un algorithme, il est plus facile et moins sujet aux erreurs de les numéroter à partir de 0, comme le font les mathématiciens: a 0 , 1 , a n , etc. Sinon, vous devez souvent ajuster par +1. et –1 pour obtenir les bonnes données, et il est facile de se tromper en créant des bugs. Par conséquent, les langages conçus pour les informaticiens utilisent généralement des nombres naturels: C, Java et Lisp comptent tous à partir de 0.

Au-delà des langages de programmation, de nombreux systèmes informatiques numérotent des éléments de 0, car ils sont habitués aux informaticiens. De plus, comme la numérotation à partir de 1 conduit à de nombreux bugs insidieux, nous sommes nombreux à l’éviter en dehors des éléments d’interface conçus exclusivement pour les utilisateurs finaux non techniques.


Java ... pour les informaticiens. LOL!
Kaz

0

La réponse simple est que le premier chiffre n'est pas 1 mais 0.

Explanation: La formule de calcul d'un nombre à plusieurs chiffres dans n'importe quelle base est la suivante:

n = sum(i=0 to n, Di^i)

WHERE 
n = numeric result
i = index (starting with 0)
Di = is the digit at index i

Prenons le système décimal, c'est celui auquel nous sommes le plus habitués.

En regardant le numéro 1234, nous pouvons l'écrire comme suit:

4 x 10^0 = 4
3 x 10^1 = 30
2 x 10^2 = 200
1 x 10^3 = 1000

in other words, sum of digits raised to the power if their index.

Donc, ce ne sont pas que les ordinateurs, nous, les gens, comptons aussi à partir de 0.


0

Un index de tableau est le décalage entre l'emplacement de mémoire de base et l'emplacement de mémoire de l'élément. L'élément i est alors Base + i. Le premier élément est situé à l'emplacement de la base, il est donc à l'emplacement 0 (base + 0).


0

Outre l'efficacité du calcul, le comptage présente un autre aspect. Il existe deux manières de donner à chaque élément d'une séquence un numéro séquentiel:

  1. Le nombre d'éléments précédents (entiers) (nombres cardinaux)
  2. La position de l'élément (nombres ordinaux)

Les âges des personnes sont des nombres cardinaux: la première année après la naissance, le bébé a 0 ans, car il est en vie depuis zéro ans.

Les années en dates sont des nombres ordinaux: la première année, Anno Domini (AD) a une année. Il n'y a pas d' année 0, comme il n'y a pas zeroth quoi que ce soit.

Les langages de programmation (tels que Matlab et Mathematica) où l'index d'un élément représente sa position dans le tableau commencent à compter à partir de 1: le premier élément. Dans d'autres langues (telles que toutes les langues basées sur le langage C), l'index d'un élément est le nombre d'éléments précédents et le premier élément est donc 0.


Bien entendu, Matteo n’a que partiellement raison lorsque l’indexation basée sur zéro est plus efficace.

element(n) = address + n * element_size

Une indexation unique peut être tout aussi efficace à condition que toutes les adresses de tableau en aient déjà une element_sizesoustraite. Cela peut être fait quand le tableau est alloué, auquel cas c'est aussi rapide:

array_address = address - element_size
element(n) = array_address + n * element_size

-1

Les ordinateurs totalisent traditionnellement les valeurs numériques à partir de zéro. Par exemple, les tableaux dans les langages de programmation en langage C commencent à partir de l'index zéro.

0… Vous bousillez différents concepts: langages de programmation, ordinateurs et calcul.

  1. Utiliser 2 états (la plupart d’entre eux le font schématiquement) signifie que vous pouvez choisir 2 chiffres pour les mapper (par exemple, se référer). "3" et "5" (ou "F" et ",") conviendront, mais vous demanderez alors pourquoi les ordinateurs comptent à partir de "3" (ou à partir de "F"). Le choix naturel est 0 et 1 évidemment.
  2. Les tableaux en Pascal commencent à 1. Ce langage est un peu plus abstrait que le C de bas niveau.
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.