29 votes

La norme C++ précise-t-elle quelque chose sur la représentation des nombres à virgule flottante ?

Pour les types T pour laquelle std::is_floating_point<T>::value es true La norme C++ spécifie-t-elle quoi que ce soit sur la manière dont les T devrait être mise en œuvre ?

Par exemple, est-ce que T doit même suivre une représentation en signe/mantisse/exponent ? Ou peut-il être complètement arbitraire ?

35voto

TartanLlama Points 1461

De N3337 :

[basic.fundamental/8]: Il existe trois types de virgule flottante : float, double et long double. Le type double offre au moins autant de précision que le float, et le type long double fournit au moins autant de précision que le double. L'ensemble des valeurs du type float est un sous-ensemble de l'ensemble des valeurs du type double. du type double est un sous-ensemble de l'ensemble des valeurs du type long double. La représentation de la valeur des types à virgule flottante est définie par l'implémentation . Les types entiers et flottants sont collectivement appelés types arithmétiques. arithmétiques. Les spécialisations du modèle standard std::numeric_limits (18.3) doivent spécifier les valeurs maximales et minimales de chaque type arithmétique pour une implémentation. valeurs maximales et minimales de chaque type arithmétique pour une implémentation.

Si vous voulez vérifier si votre implémentation utilise IEEE-754, vous pouvez utiliser std::numeric_limits::is_iec559 :

static_assert(std::numeric_limits<double>::is_iec559,
              "This code requires IEEE-754 doubles");

Il existe un certain nombre d'autres traits d'aide dans ce domaine, tels que has_infinity , quiet_NaN y más .

8voto

Zack Points 44583

La norme C comporte une "annexe" (dans C11, il s'agit de l'annexe F) qui définit ce que signifie la conformité d'une implémentation de C à la norme IEC 60559, qui succède à la norme IEEE 754. Une implémentation conforme à l'annexe F doit avoir des nombres à virgule flottante représentés par l'IEEE. Toutefois, la mise en œuvre de cette annexe est facultative ; la norme de base évite spécifiquement de dire quoi que ce soit sur la représentation des nombres à virgule flottante.

Je ne sais pas s'il existe une annexe équivalente pour le C++. Elle n'apparaît pas dans la norme N3337, mais cela pourrait simplement signifier qu'elle est distribuée séparément. L'existence de std::numeric_limits<floating-type>::is_iec559 indique que le comité C++ a au moins pensée à ce sujet, mais peut-être pas avec autant de détails que le comité C. (C'est et a toujours été une sacrée honte que la norme C++ ne soit pas exprimée comme un ensemble d'éditions de la norme C).

7voto

Jerry Coffin Points 237758

Aucune mise en œuvre particulière n'est requise. La norme C++ n'en parle pas beaucoup. La norme C entre dans les détails du modèle conceptuel supposé pour les nombres à virgule flottante, avec un signe, un exposant, un significande dans une base quelconque. b et ainsi de suite. Il est toutefois précisé qu'il s'agit d'une description et non d'une exigence de mise en œuvre (C11, note de bas de page 21) :

Le modèle à virgule flottante est destiné à clarifier la description de chaque caractéristique de la virgule flottante et n'exige pas que l'arithmétique en virgule flottante de l'implémentation soit identique.

Cela dit, bien que les détails puissent varier, il me semble, du moins au premier abord, que produire (par exemple) une implémentation conforme de double qui ne correspondait pas assez avec le modèle habituel (c'est-à-dire un significande et un exposant) serait difficile (ou du moins difficile à faire avec des performances compétitives, de toute façon). Il ne serait cependant pas particulièrement difficile de le faire varier d'autres façons, par exemple en réorganisant l'ordre ou en utilisant une base différente.

La définition de std::numeric_limits<T>::digits (et std::numeric_limits<T>::digits10 ) impliquent assez directement que ce qui est répertorié comme un type de virgule flottante doit conserver (au moins approximativement) la même précision pour tous les nombres dans une gamme assez large de magnitudes. La façon la plus évidente d'y parvenir est d'avoir un certain nombre de bits/chiffres consacrés à un significande et un autre ensemble (séparé) de bits consacrés à un exposant.

3voto

nwp Points 1665

L'idée de std::is_floating_point est de faire en sorte que des codes utilisateurs d'origines différentes fonctionnent mieux ensemble. Techniquement, vous pouvez spécifier un int como std::is_floating_point sans provoquer de comportement indéfini. Mais disons que vous avez une bibliothèque modèle qui doit diviser de manière répétée par T n . Pour accélérer les choses, la bibliothèque crée un T ni = 1 / n et remplace la division par n par multiplication par ni . Cela fonctionne très bien pour les nombres à virgule flottante, mais échoue pour les nombres entiers. Par conséquent, la bibliothèque n'effectue correctement l'optimisation que si std::is_floating_point<T>::value == true . Si vous mentez, le code fonctionne probablement toujours du point de vue de la norme, mais est incorrect d'un point de vue logique. Ainsi, si vous écrivez une classe qui se comporte comme une plus grande float le marquer comme std::is_floating_point sinon, ne le faites pas. Vous devriez ainsi obtenir un code optimal et correct.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X