math - nombres - virgule flottant ieee 754




Un peu de diversion en virgule flottante(im) précision, partie 1 (7)

La plupart des mathématiciens conviennent que:

e πi + 1 = 0

Cependant, la plupart des implémentations à virgule flottante ne sont pas d'accord. Comment pouvons-nous régler ce différend?

Je suis désireux d'entendre parler de différentes langues et implémentations, et de diverses méthodes pour rendre le résultat aussi proche de zéro que possible. Sois créatif!


En fait, comment représente-t-on i (ou j pour les ingénieurs) dans un langage de programmation conventionnel?

Dans un langage qui n'a pas de représentation native, il est généralement ajouté en utilisant OOP pour créer une classe Complex pour représenter i et j , avec une surcharge de l'opérateur pour traiter correctement les opérations impliquant d'autres nombres Complex et / ou d'autres primitives natives du langage .

Par exemple: Complex.java , C ++ <complex>


@Ryan Fox

En fait, comment représente-t-on i (ou j pour les ingénieurs) dans un langage de programmation conventionnel?

Les types de données complexes natifs sont loin d'être inconnus. Fortran l'a eu au milieu des années soixante, et le PO expose une variété d'autres langues qui les soutiennent dans le suivi de l'hist.

Et les numéros complexes peuvent être ajoutés à d'autres langages en tant que bibliothèques (avec une surcharge de l'opérateur, ils ressemblent même à des types natifs dans le code).

Mais à moins de fournir un cas particulier pour ce problème, le "non-accord" n'est qu'une expression de l'arithmétique imprécise de la machine, non? C'est comme se plaindre

float r = 2/3;
float s = 3*r;
float t = s - 2;

se termine par (t! = 0) (Au moins si vous utilisez un compilateur assez stupide) ...


Voici une courte liste d'implémentations et de langues que j'ai essayées. Il est trié par proximité à zéro:

  • Schéma: (+ 1 (make-polar 1 (atan 0 -1)))
    • 0.0+1.2246063538223773e-16i (Chez Scheme, MIT Scheme)
    • 0.0+1.22460635382238e-16i (Guile)
    • 0.0+1.22464679914735e-16i (Poulet avec des oeufs de numbers )
    • 0.0+1.2246467991473532e-16i (MzScheme, SISC, Gauche, Gambit)
    • 0.0+1.2246467991473533e-16i (SCM)
  • Common Lisp: (1+ (exp (complex 0 pi)))
    • #C(0.0L0 -5.0165576136843360246L-20) (CLISP)
    • #C(0.0d0 1.2246063538223773d-16) (CMUCL)
    • #C(0.0d0 1.2246467991473532d-16) (SBCL)
  • Perl: use Math::Complex; Math::Complex->emake(1, pi) + 1 use Math::Complex; Math::Complex->emake(1, pi) + 1
    • 1.22464679914735e-16i
  • Python: à from cmath import exp, pi; exp(complex(0, pi)) + 1 from cmath import exp, pi; exp(complex(0, pi)) + 1
    • 1.2246467991473532e-16j (CPython)
  • Ruby: require 'complex'; Complex::polar(1, Math::PI) + 1 require 'complex'; Complex::polar(1, Math::PI) + 1
    • Complex(0.0, 1.22464679914735e-16) (IRM)
    • Complex(0.0, 1.2246467991473532e-16) (JRuby)
  • R: complex(argument = pi) + 1
    • 0+1.224606353822377e-16i

Votre question me semble un peu étrange, car vous semblez suggérer que le calcul en virgule flottante est implémenté par le langage. Ce n'est généralement pas vrai, car le calcul de FP est fait en utilisant un processeur à virgule flottante dans le matériel. Mais le logiciel ou le matériel, le point flottant sera toujours inexact. C'est juste comment les flotteurs fonctionnent.

Si vous avez besoin d'une meilleure précision, vous devez utiliser une représentation numérique différente. Tout comme si vous faites des maths entiers sur des nombres qui ne tiennent pas dans un int ou long. Certains langages ont des librairies pour cela (je sais que java a BigInteger et BigDecimal), mais vous devriez utiliser explicitement ces librairies au lieu des types natifs, et les performances seraient (parfois significativement) moins bonnes que si vous utilisiez des floats.


L'analyse numérique nous enseigne que vous ne pouvez pas compter sur la valeur précise des petites différences entre les grands nombres.

Cela n'affecte pas seulement l'équation en question ici, mais peut apporter de l'instabilité à tout, de la résolution d'un ensemble quasi-singulier d'équations simultanées, à la recherche des zéros des polynômes, à l'évaluation log (~ 1) ou exp (~ 0) ( J'ai même vu des fonctions spéciales pour évaluer log (x + 1) et (exp (x) -1) pour contourner cela).

Je vous encourage à ne pas penser à la réduction à zéro de la différence - vous ne pouvez pas - mais plutôt à faire les calculs associés de manière à assurer l'erreur minimale.

Je suis désolé, ça fait 43 ans que je n'ai pas eu ça à l'université, et même si je me souviens des références, je suis sûr qu'il y a de meilleurs trucs maintenant. Je suggère cela comme point de départ.

Si cela semble un peu condescendant, je m'en excuse. Mon "Numerical Analysis 101" faisait partie de mon cours de chimie, car il n'y avait pas beaucoup de CS à cette époque. Je n'ai pas vraiment une idée de l'importance de l'analyse numérique du lieu / de l'importance dans un cours CS moderne.


Est-il possible de régler ce différend?

Ma première pensée est de regarder un langage symbolique, comme Maple . Je ne pense pas que cela compte comme virgule flottante.

En fait, comment représente-t-on i (ou j pour les ingénieurs) dans un langage de programmation conventionnel?

Peut-être un meilleur exemple est sin (π) = 0? (Ou ai-je raté le point à nouveau?)


C'est une limitation de nos architectures de calcul à virgule flottante actuelles. L'arithmétique à virgule flottante est seulement une approximation de pôles numériques comme e ou pi (ou tout ce qui dépasse la précision que vos bits permettent). J'apprécie vraiment ces nombres parce qu'ils défient la classification, et semblent avoir une plus grande entropie (?) Que même les nombres premiers, qui sont une série canonique. Un rapport défie la représentation numérique, parfois des choses simples comme ça peuvent faire sauter l'esprit d'une personne (j'adore ça).

Heureusement, des langages et des bibliothèques entiers peuvent être dédiés à des fonctions trigonométriques de précision en utilisant des concepts de notation (similaires à ceux décrits par Lasse V. Karlsen ).

Considérez une bibliothèque / un langage qui décrit des concepts tels que e et pi sous une forme compréhensible par une machine. Est-ce qu'une machine a une idée de ce qu'est un cercle parfait? Probablement pas, mais nous pouvons créer un objet - cercle qui satisfait toutes les caractéristiques connues que nous lui attribuons (rayon constant, relation de rayon à circonférence est 2 * pi * r = C). Un objet comme pi est seulement décrit par le rapport susmentionné. r & C peuvent être des objets numériques décrits par la précision que vous voulez leur donner. e peut être défini "comme le e est le nombre réel unique tel que la valeur de la dérivée (pente de la tangente) de la fonction f (x) = ex au point x = 0 est exactement 1" de wikipedia .

Question amusante.





floating-point