Types à virgule flottante de taille fixe

90

Dans les en- têtes stdint.h(C99), boost / cstdint.hpp et cstdint(C ++ 0x), il y a, entre autres, le type int32_t.

Existe-t-il des types de virgule flottante de taille fixe similaires? Quelque chose comme float32_t?

Pietro
la source
4
Pourquoi avez-vous besoin de quelque chose comme ça?
AraK
39
Vous avez besoin de quelque chose comme ça lorsque vous avez une structure de données avec une valeur à virgule flottante et que vous voulez également savoir exactement quelle est sa taille.
mob
5
@mobrule: Si vous avez juste besoin de savoir quelle est la taille, vous utilisez l' sizeofopérateur. Un type comme celui-ci serait utile lorsqu'un algorithme exige qu'il s'agisse d'une taille spécifique connue.
Stephen Canon
6
@Stephen Canon - oui, pour quand vous voulez garantir quelle est la taille. Disons qu'une instance de votre structure de données tiendra en 64 bits et pourra être transmise par valeur à une bibliothèque externe.
mob
5
@StephenCanon Envisagez une bibliothèque de sérialisation multiplateforme. Comment peut-il sizeofêtre utilisé pour résoudre le problème du rassemblement et de la suppression cohérents des types flottants?
Kyle Strand

Réponses:

47

Rien de tel n'existe actuellement dans les normes C ou C ++. En fait, il n'y a même pas de garantie que floatce soit un format binaire à virgule flottante.

Certains compilateurs garantissent que le floattype sera le format binaire IEEE-754 32 bits. Certains non. En réalité, il floats'agit en fait du type IEEE-754 singlesur la plupart des plates-formes non intégrées, bien que les mises en garde habituelles concernant certains compilateurs évaluant des expressions dans un format plus large s'appliquent.

Il existe un groupe de travail discutant de l'ajout de liaisons en langage C pour la révision 2008 de l'IEEE-754, qui pourrait envisager de recommander l'ajout d'un tel typedef. Si cela était ajouté à C, je m'attends à ce que le standard C ++ emboîte le pas ... éventuellement.

Stephen Canon
la source
3
Indépendamment de IEEE-754 ou non, cela n'empêchera toujours pas les problèmes de portabilité endian.
Mark B
1
@Pietro: changer la langue n'affectera pas la compatibilité de votre matériel, cela empêcherait seulement certains matériels de se conformer. Comment une garantie IEEE FP aiderait-elle la portabilité?
Potatoswatter
1
@Potatoswatter: Cela encouragerait les fournisseurs de matériel à fournir des solutions conformes. Si la partie a prend en charge la norme C sans avoir besoin de piratages de bibliothèque flottants et que la partie b ne le fait pas, c'est un avantage du marché pour la partie a.
Stephen Canon
2
@Potatoswatter: (Presque) personne ne se soucie de la vitesse du matériel. Nous nous soucions de la vitesse des logiciels exécutés sur le matériel. Le logiciel peut être plus rapide si le matériel sur lequel il s'exécute respecte les normes et qu'il n'a pas besoin de détecter et de corriger 15 cas particuliers différents en fonction de la plate-forme sur laquelle il s'exécute.
Stephen Canon
8
Comment pourriez-vous obtenir une meilleure portabilité en empêchant votre code de se compiler sur un certain nombre d'architectures de niche? Soit vous comptez sur les flottants comme IEEE, auquel cas votre code fonctionnera déjà sur toutes les implémentations conformes IEEE et rien d'autre, soit vous ne le faites pas, auquel cas votre code fonctionnera sur une plus large gamme de systèmes. Si C ++ garantissait la conformité IEEE, votre code ne deviendrait pas comme par magie plus portable, vous exclueriez simplement qu'il puisse jamais fonctionner sur ces architectures non conformes. Votre logique est complètement à l'envers.
jalf
29

Si vous voulez savoir si vous êtes floatdu type IEEE 32 bits, vérifiez std::numeric_limits<float>::is_iec559. C'est une constante de compilation, pas une fonction.

Si vous voulez être plus à l'épreuve des balles, std::numeric_limits<float>::digitsassurez-vous également qu'ils n'utilisent pas sournoisement la double précision standard IEEE pour float. Il devrait être 24.

En ce qui concerne long double, il est plus important de vérifier digitscar il existe quelques formats IEEE qui pourraient raisonnablement être: 128 bits (chiffres = 113) ou 80 bits (chiffres = 64).

Ce ne serait pas pratique de l'avoir en float32_ttant que tel car vous souhaitez généralement utiliser du matériel à virgule flottante, s'il est disponible, et ne pas recourir à une implémentation logicielle.

Potatoswatter
la source
Le long doubleformat sur OS X (Intel 32 bits et 64 bits) est exactement le format double étendu IEEE-754 stocké dans l'ordre petit-boutiste. Rien de génial à ce sujet. Les octets 0 à 7 contiennent le champ significand et les octets 8 et 9 contiennent les champs exposant et signe.
Stephen Canon
@Stephen: c'est une bonne nouvelle: v). Cela correspond-il aux chiffres que j'ai publiés?
Potatoswatter
1
Rappelez-vous que le double étendu (contrairement aux 754 autres formats) a un bit de significande explicite, donc 5.0La un significand de a000000000000000. Son exposant non biaisé est +2, et le double biais d'exposant étendu est 3fff, donc l'exposant biaisé pour 5,0L est 4001. Le modèle d'octet réel lorsqu'il est stocké dans l'ordre petit-boutiste est 00 00 00 00 00 00 00 a0 01 40, et si vous le voyez comme deux entiers 64 bits petit-boutiste, vous verrez exactement ce que vous avez observé.
Stephen Canon
(*) double étendu tel qu'implémenté par Intel dans le matériel, c'est-à-dire. Le format double étendu n'est pas en fait épinglé comme le sont les deux autres formats de base de IEEE-754 (1985).
Stephen Canon
@Stephen: Je suis à peu près sûr qu'en 4001little-endian est 01 40 00 00 ...Si rien d'autre, l'octet le moins significatif vient en premier. Je m'attends à ce que la séquence a0 01 40apparaisse quelque part dans le numéro (s'ils n'ont effectué qu'une rotation) mais je ne pense pas que vous ayez expliqué pourquoi a0et que vous 01 40soyez dans des moitiés complètement séparées.
Potatoswatter
18

Si vous pensez qu'avoir des typedefs tels que float32_t et float64_t n'est pas pratique pour quelque raison que ce soit, vous devez être trop habitué à votre système d'exploitation familier, compilateur, que vous ne pouvez pas trop regarder en dehors de votre petit nid.

Il existe du matériel qui exécute nativement des opérations en virgule flottante IEEE 32 bits et d'autres qui le font en 64 bits. Parfois, ces systèmes doivent même se parler, auquel cas il est extrêmement important de savoir si un double est 32 bits ou 64 bits sur chaque plate-forme. Si la plate-forme 32 bits devait effectuer des calculs excessifs sur la base des valeurs 64 bits de l'autre, nous souhaitons peut-être effectuer un cast à la précision inférieure en fonction des exigences de synchronisation et de vitesse.

Je me sens personnellement mal à l'aise d'utiliser des flotteurs et des doubles à moins de savoir exactement combien de bits ils se trouvent sur ma plate-forme. Encore plus si je dois les transférer sur une autre plate-forme via un canal de communication.

EmbeddedCoder
la source
"Personnellement, je me sens mal à l'aise d'utiliser des flotteurs et des doubles à moins de savoir exactement combien de bits ils se trouvent sur ma plate-forme. Encore plus si je dois les transférer sur une autre plate-forme via un canal de communication." - Vous voulez dire que vous utilisez des formats de fichiers texte? Avec ceux-ci, il y a l'inconvénient de la taille du fichier: un flottant de 32 a besoin de 4 octets; ceux-ci sous forme de texte ne peuvent représenter qu'un nombre à quatre chiffres ...
Pietro
3

Il est actuellement proposé d'ajouter les types suivants dans la langue:

decimal32
decimal64
decimal128

qui peut un jour être accessible via #include <decimal>.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3871.html

Trevor Hickey
la source
3
Certes, les types décimaux ne sont pas les types à virgule flottante IEEE 754.
Mike DeSimone