-3
votes

Comment pouvons-nous connaître clairement la précision en double ou float en C / C ++?

Supposons que nous ayons un nombre réel A qui a une précision infinie. Maintenant, nous avons du type flottant double ou float en C / C ++ et souhaitez représenter A à l'aide de ces types. Disons "a_f" est le nom de la variable pour A .

J'ai déjà compris comment les valeurs sont représentées, ce qui consiste en trois parties suivantes: signe, fraction et exposant. Selon les types utilisés, le nombre de bits attribués à la fraction et à l'exposant diffère et qui détermine la "précision".

Comment la précision est-elle définie dans ce sens?

est que la limite supérieure de la différence absolue entre A et a_f (| a - a_f |), ou est-ce que quelque chose d'autre?

Dans le cas de double , pourquoi la "précision" est-elle limitée par 2 ^ {- 54} ??

merci.


12 commentaires

La précision est déterminée par le nombre de bits dans la mantissie. Rien à voir avec l'exposant. Pour IEEE754 Double La réponse est de 53 mais, car c'est comme ça que c'est défini.


Quelle est la "précision"?


La norme ne fait qu'une restriction minimale. La précision réelle est la mise en œuvre définie.


@ L.f. Votre source pour cette assertion?


@ user9414424 La «précision» est de savoir quelle est votre question. Si vous ne savez pas ce que c'est que je ne comprends pas ce que vous demandez vraiment.


La précision est le nombre de bits attribués à la fraction. Le nombre de bits attribués à l'exposant n'a rien à voir avec cela.


La précision n'est pas limitée de 2 ^ (- 54). Cela semble être lu quelque chose mais pas compris.


@ user207421 hmm ... c11 5.2.4.2.2 Peut-être.


@ L.f. Mon commentaire explicitement fait référence à IEEE 754, qui est comme je l'ai décrit. Vous vous référez maintenant à la norme de projet C-2011. La question concerne C ++.


@ user207421 euh, je pensais que vous connaissiez eel.is/c++Draft/cfloat. Syn # 1 ...


@ L.f. Quand je parle spécifiquement d'IEEE 754, je ne m'attends pas à être référés à une autre norme Standard, sans citation, comme «la» standard. S'il vous plaît ne pas ajouter à la confusion.


@ user207421 Mon commentaire initial n'était pas dirigé contre vous. :)


3 Réponses :


0
votes

Par exemple, numéro 123456789 peut être représenté comme .12 * 10 ^ 9 ou peut-être .12345 * 10 ^ 9 ou ou ou ou .1234567 * 10 ^ 9 . Aucun de ceux-ci n'est une représentation exacte et certains sont meilleurs que les autres. Lequel vous accédez dépend du nombre de bits que vous avez pour la fraction. Plus de bits signifie plus de précision. Le nombre de bits utilisés pour représenter la fraction est appelé "précision".


0 commentaires

1
votes

La chose avec des points flottants est qu'ils deviennent plus d'innombrables les plus importants ou plus petits. Par exemple: xxx pré>

impression, comme prévu, false code>. P>

Cependant, le code suivant: p> xxx

impressions, inopinément, true code>, car les numéros sont si gros que vous ne pouvez pas représenter de manière significative x1 - 10 code>. Il est arrondi sur x1 code>. P>

On peut alors demander où et quelles sont les limites. Comme nous constatons les incohérences, nous avons besoin de certains outils pour les inspecter. code> et code> sont vos amis. p>

std :: NextAprès code> : p>

std :: NextAntaTer code> prend deux float code> s ou double code> s. Le premier argument est notre point de départ em> et le second représente le direction em> où nous souhaitons calculer la valeur suivante, représentable forte>. Par exemple, nous pouvons voir que: p> xxx pré>

x2 code> est légèrement supérieur à 10 code>. D'autre part: p> xxx pré>

sorties sur ma machine: p>

1.79769313486231570814527423731704356798070567525845e+308
1.7976931348623155085612432838450624023434343715745934e+308
                 ^ difference


4 commentaires

Dans le premier exemple, les deux chiffres sont parfaitement précis. Leur taille n'affecte pas cela. Il est soustraire deux numéros avec des valeurs largement différentes qui entraînent des problèmes. Et dans le monde réel, la comparaison de nombres si largement différente n'a généralement pas de sens. Les chiffres réels sont capables de représenter des différences comme ça, mais le résultat n'est pas utile.


@Petebecker J'ose être en désaccord avec " Les chiffres réels sont capables de représenter des différences comme ça, mais le résultat n'est pas utile ". Les calculs utilisés dans la physique se soucient de ces différences subtiles. Mais si vous vous souciez de précision, vous ne devriez pas utiliser double en premier lieu.


Vous parlez de différences sur l'ordre d'une partie de 10 ^ 300, qui est bien au-delà de la précision de tout instrument aujourd'hui. Les différences de cette magnitude sont bien inférieures au niveau de bruit de toute mesure.


@Petebecker Resurggene Les expansions de la théorie et de la série asimprotique dans la physique exigent ce type de valeurs et de différences non représentables par des doubles, mais je pense que ce n'est pas un lieu pour de telles discussions.



1
votes

La précision des types de points flottants est normalement définie en termes de nombre de chiffres dans la mantissa, qui peut être obtenu en utilisant std :: numeric_limits :: chiffres (où T est le type de point flottant - float , double , etc.).

Le nombre de chiffres dans la mantissa est défini en termes de radix, obtenu avec std :: numeric_limits :: radiix . .

Le nombre de chiffres et de types de types de points flottants sont définis. Je ne suis pas au courant d'une implémentation du monde réel qui prend en charge un radix ponctuel flottant autre que 2 (mais la norme C ++ n'exige pas cela).

Si le radix est 2 std :: numeric_limits :: chiffres est le nombre de bits (c'est-à-dire deux chiffres de base), et qui définit la précision de le type de point flottant. Pour les types de double précision IEEE754, qui fonctionne à 54 bits de précision - mais la norme C ++ ne nécessite pas d'implémentation d'utiliser des représentations de points flottants IEEE.

Lorsque vous stockez une valeur réelle A dans une variable de point flottant, la variable réelle stockée (ce que vous décrivez comme a_f ) est l'approximation la plus proche qui peut être représentée (en supposant des effets comme le débordement ne se produisent pas). La différence (ou la magnitude de la différence) entre les deux ne dépend pas seulement de la mantissa - elle dépend également de l'exposant à point flottant - il n'y a donc pas de limite supérieure fixe.

pratiquement (en termes très inexacts), la différence possible entre une valeur et son approximation de point flottant est liée à la magnitude de la valeur. Les variables ponctuelles flottantes ne représentent pas un ensemble de valeurs uniformément réparties entre les valeurs minimales et représentables maximales - il s'agit d'un compromis de représentation à l'aide d'une mantissie et d'un exposant, nécessaire pour pouvoir représenter une plus grande gamme de valeurs qu'une intégrale. Type de la même taille.


8 commentaires

Ni la norme C ni la norme C ++ ne nécessitent que la valeur représentative soit le résultat de la conversion d'un chiffre en un type à virgule flottante. Ils n'exigent que si le nombre est à portée de distance, la valeur inférieure la plus proche ou la plus proche est choisie, de manière définie par la mise en œuvre.


"Signification" est le terme préféré pour la partie fraction d'une représentation à virgule flottante. "MANSSA" est un ancien terme pour la partie fraction d'un logarithme. Significations sont linéaires. Les mantissas sont logarithmiques.


Il est imprécis de se référer à "stocker" un nombre réel dans une valeur de point flottante. Ceci est mieux compris (et est défini dans la norme IEEE-754) comme une opération de conversion: un nombre représenté comme étant donné qu'un chiffre décimal dans le code source ou une autre chaîne est converti de ce format décimal à un format de point flottant. De même à toute opération arithmétique comme la multiplication, le résultat du nombre réel est arrondi à une valeur représentable. Ce modèle est plus utile lors de l'analyse et de la conception des opérations de point flottant et des épreuves d'écriture. Penser au point flottant comme "stocker" un nombre réel ...


... conduit à un modèle erroné d'un numéro de point flottant comme représentant une gamme floue de nombres réels, qui conduit ensuite à des déductions incorrectes sur la manière dont ils se comportent. Chaque numéro de point flottant représente un nombre réel exactement. Si un nombre réel ne peut pas être représenté, il n'est pas "stocké" comme numéro de point flottant; Il est converti, avec arrondissement.


@ERICPOSTPISCHIL - La question était imprécise et la rédaction d'une réponse précise / complète prendrait plus de temps que je dois vérifier les détails et écrire un. IEEE-754 utilisé (introduit?) Le terme "signifiant" pour remédier à la distinction que vous soulignez, mais les termes plus anciens tels que MANTISSA sont toujours utilisés - y compris dans les récentes normes C ++ - car IEEE-754 n'est pas le seul modèle de point flottant . Ainsi, alors que j'accepte vos observations, une terminologie plus ancienne est toujours utilisée et je soupçonne de ne pas disparaître de temps bientôt


@Peter: en supposant, pour une raison quelconque, vous souhaitez choisir votre terminologie en fonction de la popularité plutôt que de la précision et de la qualité, la norme C actuelle utilise «signification» tout au long de la "Mantissa", tandis que la norme C ++ a trois utilisations de "SIGNIQUE" et une "MANTUSSA" (bien que un brouillon tardif; Je n'ai pas la version officielle).


@Petebecker IEEE-754 BINARE64 est 52 bits stockés avec 1 bits impliqués, donc total de 53, voir aussi Stackoverflow.com/questions/18409496/...


@MarkrotteveEVEL - Merci. Supprimé.