La virgule flottante actuelle (flottant C ANSI, double) permet de représenter une approximation d'un nombre réel.
Existe-t-il un moyen de représenter des nombres réels sans erreur ?
Voici une idée que j'ai eue, qui est tout sauf parfaite.
Par exemple, 1/3 est 0.33333333 ... (base 10) ou o.01010101 ... (base 2), mais aussi 0,1 (base 3)
Est-ce une bonne idée de mettre en œuvre cette "structure":
base, mantissa, exponent
donc 1/3 pourrait être 3 ^ -1
{[11] = base 3, [1.0] mantissa, [-1] exponent}
D'autres idées?
Réponses:
Tout dépend de ce que vous voulez faire.
Par exemple, ce que vous montrez est un excellent moyen de représenter des nombres rationnels. Mais il ne peut toujours pas représenter quelque chose comme ou e parfaitement.π e
En fait, de nombreuses langues telles que Haskell et Scheme ont intégré la prise en charge des nombres rationnels, les stockant sous la forme d' oùa,bsont des entiers.ab a,b
La principale raison pour laquelle ceux-ci ne sont pas largement utilisés est la performance. Les nombres à virgule flottante sont un peu imprécis, mais leurs opérations sont implémentées dans le matériel. Votre système proposé permet une plus grande précision, mais nécessite plusieurs étapes de mise en œuvre, par opposition à une seule opération qui peut être effectuée dans le matériel.
Il est connu que certains nombres réels ne sont pas calculables, tels que les nombres d'arrêt . Il n'y a pas d' algorithme ses chiffres énumérant, contrairement à , où l' on peut calculer le n ième chiffre tant que nous attendons assez longtemps.π n
Si vous voulez une vraie précision pour les choses irrationnelles ou transcendantales, vous devrez probablement utiliser une sorte de système d'algèbre symbolique, puis obtenir une réponse finale sous forme symbolique, que vous pourriez approximer à n'importe quel nombre de chiffres. Cependant, en raison des problèmes d'indécidabilité décrits ci-dessus, cette approche est nécessairement limitée. C'est toujours bon pour des choses comme l'approximation d'intégrales ou de séries infinies.
la source
Il n'y a aucun moyen de représenter tous les nombres réels sans erreur si chaque nombre doit avoir une représentation finie. Il existe un nombre incalculable de nombres réels, mais seulement de nombreuses chaînes finies de 1 et de 0 que vous pouvez utiliser pour les représenter.
la source
Votre idée ne fonctionne pas car un nombre représenté dans la base avec la mantisse m et l'exposant e est le nombre rationnel b ⋅ m - e , donc votre représentation fonctionne précisément pour les nombres rationnels et pas les autres. Vous ne pouvez pas représenter √b m e b⋅m−e par exemple.2–√
Il existe toute une branche des mathématiques calculables qui traite de l'arithmétique réelle exacte. De nombreuses structures de données pour représenter les nombres réels exacts ont été proposées: des flux de chiffres, des flux de contractions affines, des séquences de Cauchy de rationnels, des séquences de Cauchy de rationnels dyadiques, des coupes Dedekind, des séquences d'intervalles de rétrécissement, etc. sur ces idées, par exemple:
De ces iRRAM est le plus mature et le plus efficace. Marshall dans un projet expérimental, alors que le troisième est un projet étudiant, mais aussi le plus facilement accessible. Il a une très belle introduction expliquant les problèmes concernant le calcul des nombres réels, je vous recommande fortement de le regarder.
Permettez-moi de faire une remarque. Quelqu'un objectera qu'un objet infini ne peut pas être représenté par un ordinateur. Dans un certain sens, c'est vrai, mais dans un autre, ce n'est pas le cas. Nous n'avons jamais à représenter un nombre réel entier , nous n'avons besoin que d'une approximation finieà chaque étape du calcul. Ainsi, nous n'avons besoin que d'une représentation qui peut représenter un réel jusqu'à une précision donnée. Bien sûr, une fois que nous manquons de mémoire d'ordinateur, nous manquons de mémoire d'ordinateur - mais c'est une limitation de l'ordinateur, pas la représentation elle-même. Cette situation n'est pas différente de beaucoup d'autres dans la programmation. Par exemple, les gens utilisent des entiers en Python et les considèrent comme "arbitrairement grands" même s'ils ne peuvent bien sûr pas dépasser la taille de la mémoire disponible. Parfois, l'infini est une approximation utile pour un très grand nombre fini.
De plus, j'entends souvent dire que les ordinateurs ne peuvent traiter que des nombres réels calculables . Cela manque deux points importants. Premièrement, les ordinateurs ont accès aux données du monde extérieur, nous devons donc également faire l'hypothèse (non vérifiable) que le monde extérieur est également calculable. Deuxièmement, nous devons faire la distinction entre les réels qu'un ordinateur peut calculer et ceux qu'il peut représenter. Par exemple, si nous choisissons des flux de chiffres comme représentation de réels, il est parfaitement possible de représenter un réel non calculable: si quelqu'un nous le donnait, nous saurions le représenter. Mais si nous choisissons de représenter les réels comme des morceaux de code source qui calculent les chiffres, alors nous ne pourrions pas représenter les réels non calculables, évidemment.
Dans tous les cas, ce sujet est mieux abordé avec quelques lectures supplémentaires.
la source
Il existe de nombreuses implémentations efficaces du nombre rationnel, mais celle qui a été proposée à plusieurs reprises et qui peut même très bien gérer certains irrationnels est les fractions continues .
Citation de fractions continuées par Darren C. Collins :
Citation de Mathworld - Fractions continues périodiques
c'est-à-dire que toutes les racines peuvent être exprimées en fractions continues périodiques.
Il y a aussi une fraction continue exacte pour π qui m'a surpris jusqu'à ce que @AndrejBauer souligne qu'il ne l'est pas.
la source
Il y a un certain nombre de suggestions "réelles exactes" dans les commentaires (par exemple fractions continues, transformations fractionnaires linéaires, etc.). Le problème typique est que même si vous pouvez calculer les réponses à une formule, l'égalité est souvent indécidable.
Cependant, si vous êtes juste intéressé par les nombres algébriques, alors vous avez de la chance: la théorie des champs fermés réels est complète, o-minimale et décidable. Cela a été prouvé par Tarski en 1948.
Mais il y a un hic. Vous ne voulez pas utiliser l'algorithme de Tarski, car il appartient à la classe de complexité NONELEMENTARY, qui est aussi peu pratique que les algorithmes peu pratiques peuvent obtenir. Il existe des méthodes plus récentes qui réduisent la complexité à DEXP, qui est la meilleure que nous connaissons actuellement.
Notez que le problème est NP-difficile car il inclut SAT. Cependant, il n'est pas connu (ou supposé) être dans NP.
EDIT Je vais essayer d'expliquer cela un peu plus.
Le cadre pour comprendre tout cela est un problème de décision connu sous le nom de Satisfiability Modulo Theories, ou SMT pour faire court. Fondamentalement, nous voulons résoudre SAT pour une théorie basée sur la logique classique.
Nous commençons donc avec une logique classique de premier ordre avec un test d'égalité. Les symboles de fonction que nous voulons inclure et leurs axiomes déterminent si la théorie est décidable ou non.
Il y a beaucoup de théories intéressantes exprimées dans le cadre SMT. Par exemple, il existe des théories sur les structures de données (par exemple des listes, des arbres binaires, etc.) qui sont utilisées pour aider à prouver que les programmes sont corrects, et la théorie de la géométrie euclidienne. Mais pour notre objectif, nous examinons des théories de différents types de nombres.
L'arithmétique de Presburger est la théorie des nombres naturels avec addition. Cette théorie est décidable.
L'arithmétique peano est la théorie des nombres naturels avec addition et multiplication. Cette théorie n'est pas décidable, comme l'a célèbre démontré Gödel.
L'arithmétique de Tarski est la théorie des nombres réels avec toutes les opérations sur le terrain (addition, soustraction, multiplication et division). Fait intéressant, cette théorie est décidable. C'était un résultat hautement contre-intuitif à l'époque. Vous pourriez supposer que parce que c'est un "surensemble" des nombres naturels, c'est "plus difficile", mais ce n'est pas le cas; comparer la programmation linéaire sur les rationnels avec la programmation linéaire sur les entiers, par exemple.
Il ne peut pas sembler évident que la satisfaction est tout ce dont vous avez besoin, mais c'est le cas. Par exemple, si vous souhaitez tester si la racine carrée positive de 2 est égale à la racine cubique réelle de 3, vous pouvez l'exprimer comme le problème de satisfiabilité:
Alfred Tarski (1948), Une méthode de décision pour l'algèbre élémentaire et la géométrie .
la source
Il est possible de représenter exactement une très grande classe de nombres appelés nombres algébriques , en les traitant comme des racines de polynômes.
la source
la source
Vous ne pouvez pas représenter tous les nombres réels dans un ordinateur, mais vous pouvez en représenter plusieurs. Vous pouvez utiliser des fractions qui représenteraient plus de nombres que de flottants. Vous pouvez également faire des choses plus sophistiquées comme représenter des nombres comme racine d'un polynôme avec une approximation qui, selon la méthode newtons, convergera vers le nombre.
la source
Il est possible de représenter n'importe quel nombre avec précision où les entrées sont représentables en les stockant comme une chaîne d'opérations.Par exemple, vous stockez
1/3
car1 divided by 3
, en gérant l'annulation des opérations, vous pouvez simplifier l'opération suivante pour donner une réponse exacte(1/3) * 3
. Cela peut également gérer des situations où vous avez connu des irrationnels,π
par exemple en les conservant dans vos calculs.Cependant, cela nécessite une quantité croissante de mémoire pour chaque nombre et - en supposant que votre simplificateur n'est pas parfait - cela nécessitera probablement une quantité toujours croissante pour les valeurs sur lesquelles vous travaillez beaucoup.
la source