Les ordinateurs ont du mal à stocker des nombres fractionnaires où le dénominateur est autre chose qu'une solution à 2 ^ x. En effet, le premier chiffre après la décimale vaut 1/2, le deuxième 1/4 (ou 1 / (2 ^ 1) et 1 / (2 ^ 2)) etc.
Pourquoi traiter toutes sortes d'erreurs d'arrondi alors que l'ordinateur aurait pu simplement stocker la partie décimale du nombre comme un autre nombre entier (ce qui est donc exact?)
La seule chose à laquelle je peux penser est la répétition des décimales (en base 10), mais il aurait pu y avoir une solution de bord (comme nous l'avons actuellement avec l'infini).
numbers
numeric-precision
SomeKittens
la source
la source
Réponses:
Il existe en fait des modes de nombres qui font cela.
L'arithmétique décimale codée binaire (BCD) a le travail informatique en base 10. La raison pour laquelle vous rencontrez rarement cela est qu'il gaspille de l'espace: chaque chiffre individuel d'un nombre prend au moins quatre bits, alors qu'un ordinateur pourrait autrement stocker jusqu'à 16 valeurs dans cet espace. (Il peut également être plus lent, mais il est possible d'avoir des calculs BCD accélérés par le matériel qui fonctionnent très bien.). C'est, en fait, exactement ce que font la plupart des calculatrices, c'est pourquoi il existe certaines classes de problèmes d'arrondi que vous ne rencontrerez jamais sur un Casio à 5 $ qui mangera votre déjeuner sur un ordinateur de bureau.
L'autre voie que vous pouvez emprunter est d'utiliser des nombres rationnels, c'est-à-dire un numérateur et un dénominateur, stockés sous forme d'entiers. Il est en fait disponible dans presque toutes les langues, est exact et vous permet de tout stocker dans des formats binaires natifs. Le problème est qu'en fin de compte, les utilisateurs ne veulent probablement pas voir des fractions comme 463/13, ni même 35 et 8/13. Ils veulent voir 35.615 ..., et au moment où vous y arrivez, vous êtes confronté à tous les problèmes typiques. Ajoutez que ce format prend encore plus d' espace et peut être beaucoup plus lent que l'arithmétique à virgule flottante, et vous ne trouverez aucun ordinateur utilisant ce format par défaut.
Donc: les ordinateurs peuvent faire ce que vous voulez, mais c'est lent et cela gaspille de l'espace, donc ils ne le font que lorsqu'ils en ont vraiment besoin. Le reste du temps, la vitesse et les économies d'espace de la virgule flottante sont un meilleur compromis.
la source
decimal
est implémenté: stackoverflow.com/a/5019178/174335 Ce n'est pas BCD car il n'y a pas de représentation individuelle des chiffres décimaux et ce n'est pas un point fixe.Il existe de nombreuses façons de stocker des nombres fractionnaires, et chacun d'eux présente des avantages et des inconvénients.
La virgule flottante est, de loin, le format le plus populaire. Il fonctionne en codant un signe, une mantisse et un exposant de base 2 signé en entiers, et en les regroupant en un tas de bits. Par exemple, vous pourriez avoir une mantisse 32 bits de
0.5
(codé comme0x88888888
) et un exposant signé 32 bits de+3
(0x00000003
), qui décoderait en4.0
(0.5 * 2 ^ 3
). Les nombres à virgule flottante sont rapides, car ils sont implémentés dans le matériel et leurs échelles de précision avec une taille absolue, c'est-à-dire que plus le nombre est petit, meilleure est votre précision absolue, de sorte que l'erreur d'arrondi relative reste constante avec la taille absolue. Les flotteurs sont excellents pour les valeurs échantillonnées à partir d'un domaine continu, telles que les longueurs, les niveaux de pression acoustique, les niveaux de lumière, etc., et pour cette raison, ils sont couramment utilisés dans le traitement audio et d'image, ainsi que dans l'analyse statistique et les simulations physiques. Leur plus gros inconvénient est qu'ils ne sont pas exacts, c'est-à-dire qu'ils sont sujets à des erreurs d'arrondi et qu'ils ne peuvent pas représenter avec précision toutes les fractions décimales. Tous les langages de programmation traditionnels ont une sorte de flotteur.Un point fixefonctionne en utilisant des entiers suffisamment grands et en réservant implicitement une partie de leurs bits pour la partie fractionnaire. Par exemple, un nombre à virgule fixe de 24,8 bits réserve 24 bits pour la partie entière (signe compris) et 8 bits pour la partie fractionnaire. Décaler ce nombre de 8 bits vers la droite nous donne la partie entière. Les nombres à virgule fixe étaient populaires lorsque les unités matérielles à virgule flottante étaient rares ou au moins beaucoup plus lentes que leurs homologues entiers. Bien que les nombres à virgule fixe soient un peu plus faciles à gérer en termes d'exactitude (ne serait-ce que parce qu'ils sont plus faciles à raisonner), ils sont inférieurs aux flottants à presque tous les autres égards - ils ont moins de précision, une plage plus petite et parce que plus des opérations sont nécessaires pour corriger les calculs du décalage implicite, les mathématiques à virgule fixe sont aujourd'hui souvent plus lentes que les mathématiques à virgule flottante.
Les types décimaux fonctionnent un peu comme des flottants ou des nombres à virgule fixe, mais ils supposent un système décimal, c'est-à-dire que leur exposant (implicite ou explicite) code la puissance de 10, pas la puissance de 2. Un nombre décimal pourrait, par exemple, coder une mantisse de
23456
et un exposant de-2
, et cela s'élargirait à234.56
. Les décimales, parce que l'arithmétique n'est pas câblée dans le CPU, sont plus lentes que les flottants, mais elles sont idéales pour tout ce qui implique des nombres décimaux et a besoin que ces nombres soient exacts, avec l'arrondi se produisant à des endroits bien définis - calculs financiers, tableaux de bord, etc. Certains langages de programmation ont des types décimaux intégrés (par exemple C #), d'autres nécessitent des bibliothèques pour les implémenter. Notez que si les décimales peuvent représenter avec précision des fractions décimales non répétitives, leur précision n'est pas meilleure que celle des nombres à virgule flottante; choisir des décimales signifie simplement que vous obtenez des représentations exactes de nombres qui peuvent être représentés exactement dans un système décimal (tout comme les flottants peuvent représenter exactement des fractions binaires).Les nombres rationnels stockent un numérateur et un dénumérateur, en utilisant généralement une sorte de type entier bignum (un type numérique qui peut augmenter aussi grand que le permettent les contraintes de mémoire de l'ordinateur). C'est le seul type de données du groupe qui peut modéliser avec précision des nombres comme
1/3
ou3/17
, ainsi que des opérations sur eux - les rationnels, contrairement aux autres types de données, produiront des résultats corrects pour des choses comme3 * 1/3
. Les calculs sont assez simples, bien que trouver un algorithme de factorisation efficace soit plutôt difficile. Certains langages de programmation ont des types rationnels intégrés (par exemple Common Lisp). Les inconvénients des rationnels incluent qu'ils sont lents (de nombreuses opérations nécessitent de réduire les fractions et de factoriser leurs composants), et que de nombreuses opérations courantes sont difficiles ou impossibles à implémenter, et la plupart des implémentations dégraderont le rationnel en flottant lorsque cela se produira (par exemple lorsque vous appelezsin()
sur un rationnel).BCD (Binary Coded Decimal) utilise des "quartets" (groupes de 4 bits) pour coder des chiffres individuels; comme un quartet peut contenir 16 valeurs différentes, mais que les nombres décimaux ne nécessitent que 10, il y a 6 valeurs "illégales" par quartet. Comme les décimales, les nombres BCD sont exacts en décimales, c'est-à-dire que les calculs effectués sur les nombres décimaux fonctionnent comme s'ils le faisaient avec un stylo et du papier. Les règles arithmétiques pour BCD sont quelque peu maladroites, mais l'avantage est que les convertir en chaînes est plus facile qu'avec certains autres formats, ce qui est particulièrement intéressant pour les environnements à faibles ressources comme les systèmes embarqués.
Les chaînes , oui, les vieilles chaînes simples, peuvent également être utilisées pour représenter des nombres fractionnaires. Techniquement, c'est très similaire à BCD, seulement qu'il y a un point décimal explicite et que vous utilisez un octet complet par chiffre décimal. En tant que tel, le format est inutile (seulement 11 des 256 valeurs possibles sont utilisées), mais il est plus facile à analyser et à générer que BCD. De plus, comme toutes les valeurs utilisées sont "peu suspectes", inoffensives et neutres sur la plate-forme, les nombres codés en chaîne peuvent voyager sans problème sur les réseaux. Il est rare de trouver des calculs arithmétiques directement sur les chaînes, mais c'est possible, et lorsque vous le faites, ils sont tout aussi décimaux que les autres formats décimaux (décimaux et BCD).
la source
Les nombres à virgule flottante représentent une vaste gamme de valeurs, ce qui est très utile lorsque vous ne savez pas à l'avance quelles pourraient être les valeurs, mais c'est un compromis. Représenter 1/10 ^ 100 avec un deuxième entier ne fonctionnerait pas.
Certaines langues (et certaines bibliothèques) ont d'autres caractéristiques. Lisp a traditionnellement des entiers de précision infinie. Cobol a des calculs avec des nombres décimaux à virgule fixe.
Vous devez sélectionner votre représentation numérique appropriée au domaine problématique.
la source
Il semble que vous décriviez des nombres à virgule fixe .
Gardez à l'esprit que le stockage de la partie fractionnaire d'un nombre dans un emplacement séparé est exactement identique à la création d'un espace unique, deux fois plus long, et au stockage de la partie entière et fractionnaire dans les deux moitiés séparées. En d'autres termes, cela revient à stocker le nombre sous forme d'entier mais simplement à supposer un nombre fixe d'espaces décimaux.
Normalement, les nombres à virgule flottante sont stockés à l'aide d'une variation binaire de la notation scientifique, car ce qui compte généralement, ce sont les chiffres significatifs. De nombreuses autres méthodes existent cependant. Les nombres décimaux à virgule fixe sont couramment utilisés par exemple pour stocker des valeurs monétaires, où la précision est critique jusqu'à un certain nombre entier de décimales mais le nombre de chiffres décimaux requis ne change jamais.
la source
Cela s'appellerait BCD, je pense que vous pouvez toujours l'utiliser si vous le voulez vraiment. Mais ça ne vaut pas vraiment le coup car:
la source
La réponse courte est que la virgule flottante a été conçue pour des calculs scientifiques. Il peut stocker un nombre avec (jusqu'à) un nombre spécifié de chiffres significatifs, ce qui correspond étroitement à la façon dont la précision est mesurée dans la plupart des calculs scientifiques.
Cela a tendance à être pris en charge par le matériel, en grande partie parce que les calculs scientifiques ont tendance à être ceux qui ont le plus bénéficié du support matériel. Par exemple, les calculs financiers sont souvent effectués avec d'autres formats - mais les logiciels financiers font généralement assez peu de calculs réels que même si les formats nécessaires ne sont pris en charge que par les logiciels, les performances restent parfaitement adéquates pour la plupart des logiciels financiers.
la source