Comment les ordinateurs gèrent-ils le système décimal ?

Le problème exposé dans ce sujet a été résolu.

Bonjour,

tout (ou quasiment tout) est dans le titre. Je sais qu'il existe le BCD, mais je crois savoir qu'il est utilisé que par certaines calculatrices. Lesquelles et pourquoi ?

Sinon, je suppose que les ordinateurs se débrouillent autrement. Je suppose donc que tous les nombres écrits en décimal sont analysés comme des chaînes de symboles, et à chaque fois que l'ordinateur veut comprendre la valeur, il doit les calculer (en regardant dans sa table que valent les chiffres de 0 à 9 en binaire, puis il multiplie par les bonnes puissances de 10 et il additionne). Et je suppose qu'on pourrait accélérer ça en stockant des tableaux de correspondances binaire-décimal plus grands que simplement de 0 à 9. Mais je n'y suis sûrement pas du tout, car ça a l'air très moche et très lent (même si parfois on serait surpris). Comment cela fonctionne-t-il en réalité ?

Il me semble que ce genre de calcul à lieu d'être vraiment partout et tout le temps. Par exemple, quand j'écris un programme, est-ce au compilateur de gérer la conversion de mes nombres de décimal à binaire, au système d'exploitation d'appeler une instruction du processeur faite pour, ou encore quelque chose d'autre ?

Merci beaucoup !

+0 -0

Il ne les gère pas.

Je pense que tu confonds les nombres et leur représentation. $42_{10}$ et $101010_2$, c'est la même chose. $42_{10} \times 5_{10}$ et $101010_2 \times 101_2$, c'est toujours la même chose. Les résultats donnent $210_{10}$ et $11010010_2$, qui sont encore identiques (tu peux poser la multiplication binaire pour ce second cas, ça marche comme la décimale, sauf que la retenue commence quand tu dépasses $1$).

Quand dans ton code source, tes nombres sont écrits en représentation décimale, ce n'est qu'une notation pour la rendre lisible par l'humain. En interne, quand le programme est compilé, les nombres se trouvent stockés dans des structures adaptées, que le processeur sait traiter.

Un int par exemple n'est pas un nombre en représentation décimale, c'est juste un nombre. Il possède sa représentation interne, qui reste à sa discrétion.

Il existe des opérations pour passer d'une représentation quelconque à un nombre, et d'un nombre à une représentation, elles ne sont pas très complexes à réaliser. En effet, chaque chiffre (caractère) est associé à sa valeur numérique ({'0': 0, '1': 1, ..., '9': 9}), et le nombres est construit par additions et multiplications successives.

Salut,

Il me semble que ce genre de calcul à lieu d'être vraiment partout et tout le temps. Par exemple, quand j'écris un programme, est-ce au compilateur de gérer la conversion de mes nombres de décimal à binaire, au système d'exploitation d'appeler une instruction du processeur faite pour, ou encore quelque chose d'autre ?

jtruc34

Cela dépend de la source de la valeur décimale. S'il s'agit d'une constante, c'est le compilateur qui va se charger de la convertir dans le bon format de sorte qu'elle soit directement utilisée comme opérande d'une instruction. Si en revanche la valeur provient d'un périphérique (clavier, réseau, disque dur, etc.), c'est une routine qui devra se charger de la conversion (s'il y a lieu d'en avoir une).

Édit : semi-grillé.

+0 -0

entwanne, tu joues un peu sur les mots. J'aurais peut-être dû mettre ça comme titre : « Comment les ordinateurs font-ils pour comprendre les représentations de nombre qu'ils n'utilisent pas physiqument dans leurs circuits ? » ? Je sais bien que l'ordinateur stocke tout en binaire et que toutes les bases sont strictement équivalentes. Mais quand l'ordinateur reçoit un truc que je lui écrit dans une base qu'il ne comprend pas (genre base 10), il doit bien faire quelque chose pour changer de représentation.

Mais tu m'as répondu après, donc si je comprends bien, l'algorithme de conversion chaîne de symboles en nombre est bien celui que j'avais mis en hypothèse dans ma question et qui me semblait bourrin, et il est utilisé à chaque fois que l'ordinateur doit comprendre un nombre pas représenté en base 2 ?

Et ce que je voulais savoir, aussi, c'est si c'était fait niveau processeur ou niveau OS. J'entends, s'il y a une instruction ou un ensemble d'instructions du processeur juste faites pour, ou si c'est l'OS qui doit contenir cette routine, sans quoi à chaque fois que je veux écrire, par exemple, sur l'entrée standard, je ne peux le faire qu'en utilisant la seule représentation que comprend l'ordinateur ?

Merci beaucoup !

+0 -0

Le fait que l'ordinateur utilise une représentation binaire pour stocker les nombres, c'est du détail d'implémentation, et ça ne doit a priori pas influer sur ton travail (mis à part si tu es vraiment sur du bas-niveau).

L'ordinateur pourrait fonctionner avec des représentations trinaires des nombres, ce serait pareil, tu aurais ton type int et les différentes opérations applicables dessus. Il ne comprend pas plus la notation binaire que l'on utilise que la notation décimale (les caractères 0 et 1 que l'on utilise pour les chiffres n'ont pas de signification pour lui).

Alors la question n'est pas de passer d'une représentation décimale à une représentation binaire, mais d'une représentation décimale à un nombre compréhensible par l'ordinateur (int). Pour cela, il convient donc de créer un nombre en itérant sur les chiffres de notre représentation.

Tu parlais de correspondances binaire-décimal, mais non, ce sont juste des correspondances chiffre-nombre, le chiffre étant un caractère de la représentation.

Par exemple, en Python, on pourrait écrire facilement une fonction de conversion d'une chaîne vers un nombre :

1
2
3
4
5
6
7
import string

def int_of_str(s, base=string.digits):
    n = 0
    for c in s:
        n = n * len(base) + base.index(c)
    return n

Qui fonctionne très bien avec la base 10 (par défaut), mais aussi avec n'importe quelle autre.

Le processeur est construit pour manipuler les nombres tels qu'il les connaît. C'est aux compilateurs de se charger de les stocker dans le bon format.

Tu considères peut-être que je joue sur les mots, mais j'ai rencontré tellement de gens qui avaient du mal à différencier le nombre de sa représentation que je préfère insister.

Tu considères peut-être que je joue sur les mots, mais j'ai rencontré tellement de gens qui avaient du mal à différencier le nombre de sa représentation que je préfère insister.

entwanne

D'accord, d'accord, je voulais juste éviter de m'encombrer d'un formalisme particulièrement lourd.

Le fait que l'ordinateur utilise une représentation binaire pour stocker les nombres, c'est du détail d'implémentation, et ça ne doit a priori pas influer sur ton travail (mis à part si tu es vraiment sur du bas-niveau).

entwanne

Le but n'étais pas de poser une question existentielle. :lol:

Mais la compilation n'est pas le seul endroit où l'utilisateur écrit un nombre en représentation décimale. Par exemple, si je sors l'application calculatrice, je vais pas écrire mes nombres en binaire. Qui va se charger de changer la représentation afin que le processeur puisse faire les calculs ?

Et de nouveau, quand je veux afficher sur la sortie standard le contenu d'une case mémoire, qui se charge de changer la représentation pour que je puisse la lire au format décimal ?

Ah, et on a aussi complètement éludé le BCD. Qui l'utilise et pourquoi ?

Merci !

+0 -0

Dans tous les cas, ce sont des fonctions telles que celle que j'ai décrite qui sont utilisées. On passe à une représentation textuelle du nombre au nombre en lui-même tel que sait le comprendre la machine.

Pour l'écriture d'un nombre, c'est l'opération inverse, on formate une chaîne de caractère à partir d'un nombre en mémoire. C'est un poil plus compliqué, mais ça se fait plutôt bien.

Pour le BCD, je ne peux pas te répondre, je découvre ce format à l'instant.

Le BCD sert en autre dans la norme IEEE 754 pour représenter les décimales de nombres à virgules de manière exacte.

Pour faire simple, la représentation habituelle est binaire, ce qui fait que certains nombres à virgule seront approximés par rapport à leur version décimale. Dans certains cas, c'est indésirable (banque, finance…), et on va utiliser le BCD pour avoir des décimales exactes codées en binaire.

Ah, et on a aussi complètement éludé le BCD. Qui l'utilise et pourquoi ?

Et bien pour autant que je sache, le BCD est très peu utilisé. Ce code fait perdre en performance car sur un même nombre de bit, tu représentes énormément moins de nombre. Il est utilisé sur certain composant électronique qui représente les nombres digits par digits. C'est le cas de certains afficheurs 7 segments par exemple.

Mais la compilation n'est pas le seul endroit où l'utilisateur écrit un nombre en représentation décimale. Par exemple, si je sors l'application calculatrice, je vais pas écrire mes nombres en binaire. Qui va se charger de changer la représentation afin que le processeur puisse faire les calculs ?

Je ne sais pas dans quel langage tu codes, mais si tu codes un peu en C ou en C++, tu t’apercevra vite que c'est en effet un problème récurrent, c'est pourquoi de nombreuses fonctions répondent à ce besoin. printf() se charge de la traduction, de même pour scanf, cin::operator>>, cout::operator<<, pour le traitement on a plutôt itoa()/atoi(), to_string() etc…

pour faire la traduction, il suffit d'écrire une fonction qui fait la même chose que ce que l'on fait lorsqu'on lit un nombre. Souvenez vous de la façon dont vous avez appris à le lire. ex: 1394 Il y a 4 chiffre le premier a un "poids" de 103 le second a un "poids" de 102 le troisième a un "poids" de 101 le quatrième a un "poids" de 100

les chiffres se suivants dans la table ascii, on peut avoir sa valeur en faisant '1'-'0' (spoil : ça fait 1) ainsi tu as ton tableau de char : char* nombre tu en lis sa longueur (petit algo pas compliqué, mais j'ai la flemme de l'écrire) : length et tu calcul ton nombre :

1
2
3
4
5
int n=0;
for(i=0; i<length; ++i)
{
    n+=(nombre[i]-'0')*10^(length-i);
}

(oui, c'est pas vraiment du c++, la puissance n'est pas comme ça et la chaine de caractère serait un string, mais c'est plus compréhensible comme ça je pense)

Pour les double, float, etc… c'est un peu plus complexe mais c'est la même idée

D'accord ! Donc c'est l'OS qui s'en occupe ? Ou le BIOS (qui porterait bien son nom) ?

Non, c'est ton langage qui va s'en charger en fait, sa bibliothèque standard s'il y en a un comme le langage C ou C++ dont printf et d'autres fonctions font ce type de conversions.

Ce n'est pas le rôle de l'OS ou du BIOS.

+0 -0

D'accord ! Donc c'est l'OS qui s'en occupe ? Ou le BIOS (qui porterait bien son nom) ?

jtruc34

Non. Ce sont les compilateurs.

Et pour les entrées utilisateurs que tu veux convertir au sein de ton programme, ce sont les fonctions de la bibliothèque standard du langage.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte