2
votes

Arithmétique sûre avec des nombres inférieurs à la précision de la machine?

Cela semble être une question très basique, mais je ne suis toujours pas sûr de bien comprendre.

Disons que j'ai défini des nombres très petits et très grands

    double e = 1.602176634e−19;
    double h = 6.62607015e−34;
    double col = 299792458;
    double epsi = 8.8541878128e−12;

et que vous souhaitez les utiliser pour de l'arithmétique. Est-il sûr de le faire en double précision où seuls 16 chiffres sont significatifs?

EDIT: Prenons un exemple. Disons que nous voulons obtenir la vitesse de la lumière en unités atomiques. Il est défini comme:

    double c = 2 * epsi * h * col / (e * e);

    constexpr double a = 1.53636e-34;
    constexpr double b = 6.12362e-36;
    constexpr double c = 6.92956e+19;

Nous ne nous soucions évidemment pas de tout ce qui se passe après la neuvième décimale ou alors. Ce qui nous importe, c'est que ce qui précède est systématiquement évalué à 137,035999 ....

EDIT2: La formule était erronée.


13 commentaires

Cela dépend de ce que vous entendez par sécurité et de ce que vous voulez faire. L'arithmétique en virgule flottante est toujours sensible aux erreurs d'arrondi, d'autant plus près de ses limites.


Dépend également de l'arithmétique que vous proposez de faire. La multiplication et la division ont des modes de défaillance différents (moins?) Que l'addition et la soustraction.


Cela pourrait être pertinent s'il s'avère que la réponse est que ce n'est pas sûr: en.wikipedia.org/ wiki /…


La précision (la longueur du nombre) n’a pas grand-chose à voir avec la plage ( petite ou grande le nombre).


Plus précisément, je travaille sur un programme de chimie quantique qui doit donc utiliser des constantes naturelles. Ce que je veux dire par safe, c'est qu'il est évident que nous voulons obtenir des résultats fiables, cohérents et, bien sûr, numériquement corrects pour une entrée particulière.


Les nombres que vous montrez ont environ 7 chiffres décimaux de précision.


Si vous souhaitez ajouter des informations à votre question, veuillez la modifier .


@EigenGrau En ce qui concerne la fiabilité, la cohérence et l'exactitude, il est important de comprendre que les doubles ne fournissent pas toujours des résultats mathématiquement corrects exacts. Notamment, la plupart des opérations mathématiques commutatives ne sont pas commutatives avec des doubles s. Certaines identités mathématiques ne tiennent pas tout à fait avec les doubles s. Voir Le calcul en virgule flottante est-il cassé? . Les doubles ne sont qu'une bonne approximation des mathématiques réelles.


A lire: Ce que tout informaticien devrait savoir sur Floating-Point Arithmétique . Aussi: Parfois, le calcul en virgule flottante est parfait < / a>.


Comme le soulignent la plupart des commentaires, vous semblez confondre précision avec plage . Le fait que les nombres soient minuscules est un problème de plage . La précision concerne la quantité de chiffres. Bien sûr, si vous faites a + c , cela vous donnera probablement == c . Vous pouvez toujours utiliser long double , de toute façon.


La grande majorité des problèmes de précision surviennent lors de l'ajout ou de la soustraction de valeurs de différentes amplitudes. La question parle de multiplication et de division qui sont sûres tant que la gamme est correcte. OP quelles additions / soustractions allez-vous faire? Les magnitudes correspondront-elles à peu près?


En cas de doute, vous pouvez utiliser une bibliothèque multiprécision , telle que Boost.Multiprecision et comparez les résultats. Boost.Multipresions peut également envelopper d'autres bibliothèques (telles que GMP) et (au moins partiellement) fonctionne avec des fonctions de Boost.Math.


Dans votre exemple, la double précision semble suffisante: wandbox.org/permlink/HppugNq1ri6pExlR (notez qu'il est également la précision quad de Boost utilisée). Quel est le problème avec le résultat 137.036?


3 Réponses :


1
votes

La précision relative des nombres à virgule flottante IEEE-754 utilisant 64 bits (généralement double en C ++) est constante * pour les valeurs avec des magnitudes comprises entre 10 -308 et 10 308 .

Dans cette plage, vous pouvez vous attendre à environ 15 à 16 chiffres décimaux significatifs après la virgule décimale lorsque vous écrivez les nombres dans notation scientifique normalisée .

* Eh bien, reste dans une marge étroite:
https://en.wikipedia.org/wiki/IEEE_754 -1985 # / media / File: IEEE_754_relative_precision.svg


5 commentaires

Je suis curieux de savoir à quoi sert le vote défavorable. Je ne vois aucune erreur dans cette réponse, alors ce serait bien si quelqu'un pouvait la signaler.


La précision est mesurée en chiffres significatifs, et non après la virgule décimale. C'est à dire. le premier chiffre différent de 0 à partir de la gauche est le plus significatif.


@MaximEgorushkin En notation scientifique , ces deux descriptions sont équivalentes (plus / moins un). Vous pourriez également vous opposer à l'expression «chiffres décimaux de précision», que je suis sur le point de modifier.


@MaxLanghof 0.003e3 est aussi une notation scientifique. Vous voudrez peut-être être plus précis.


@MaximEgorushkin Ajout de "normalisé" pour être suffisamment précis. Merci d'aider à améliorer cette réponse!



1
votes

La fonction que vous utilisez (par exemple, sqrt () ou tan () , par exemple) est responsable de l'étendue de la précision requise: Par conséquent, selon ce qui est enseigné dans Analyse numérique , vous devez déterminer l'erreur prévisible qui se produit dans un tel appel de fonction. En général, vous ne pouvez garantir que légèrement moins que la garantie de précision minimale qui peut être supposée à partir de l'opération de concaténation lors des appels de fonction.

REMARQUE: balise [numerical-analysis]


0 commentaires

1
votes

Le degré de sécurité dépend de la façon dont vous définissez «sûr», gardez simplement à l'esprit que les mathématiques en virgule flottante en C ++ ne sont qu'une approximation. Vous avez mentionné que vous vouliez faire de la physique et des calculs connexes, et comme tout est une approximation en physique, je ne vois pas que cela va mal. En fait, double est le meilleur outil pour votre cas. C'est un stockage efficace, rapide et raisonnablement précis. Le fait est que la taille du nombre n'a pas grand-chose à voir avec la précision.


0 commentaires