2008-11-02 23 views
2

Je cherche des suggestions sur la façon de trouver les tailles (en bits) et la plage de nombres à virgule flottante d'une manière indépendante de l'architecture. Le code pourrait être construit sur différentes plates-formes (AIX, Linux, HPUX, VMS, peut-être Windoze) en utilisant différents drapeaux - les résultats devraient donc varier. Le signe, j'ai seulement vu comme un bit, mais comment mesurer la taille de l'exposant et la mantisse?Utilisation de C: Comment puis-je déterminer les tailles des composants d'un point flottant?

Répondre

3

Regardez les valeurs définies dans float.h. Ceux-ci devraient vous donner les valeurs dont vous avez besoin.

1

Le nombre de bits utilisés pour stocker chaque champ dans un nombre à virgule flottante ne change pas.

     Sign  Exponent Fraction Bias 
Single Precision 1 [31]  8 [30-23]  23 [22-00]   127 
Double Precision 1 [63] 11 [62-52]  52 [51-00]  1023 

EDIT: Comme l'a souligné Jonathan dans les commentaires, je laisse le type long double. Je vais laisser sa décomposition des bits comme un exercice pour le lecteur. :)

+0

Non vrai, pour certaines valeurs de true; ^) ~ Il existe un petit nombre de plates-formes qui n'utilisent pas IEEE754. Mais pour la plupart, vous êtes bien sûr correct. –

+0

Vous avez manqué un long double. –

+0

@Don: * Très * petites valeurs de vrai. :) –

2

Son relativement facile à trouver:

décimal ou binaire;

myfloat a = 2.0, 
     b = 0.0; 

for (int i=0; i<20; i++) 
    b += 0.1; 

(a == b) => decimal, else binary 

Raison: Tous les systèmes binaires peuvent représenter 2.0, mais tout système binaire auront un terme d'erreur pour représenter 0,1. En accumulant vous pouvez être sûr que ce terme d'erreur ne disparaîtra pas comme en arrondissant: par ex. 1.0 == 3.0 * (1.0/3.0), même dans les systèmes binaires

longueur Mantisse:

Myfloat a = 1.0, 
     b = 1.0, 
     c, 
     inc = 1.0; 

int mantissabits = 0; 

do { 
mantissabits++; 
inc *= 0.5; // effectively shift to the right 
c = b+inc; 
} while (a != c); 

Vous ajoutez la baisse des termes jusqu'à la capacité de la mantisse. Il renvoie 24 bits pour float et 53 bits pour double ce qui est correct (La mantisse elle-même ne contient que 23/52 bits, mais comme le premier bit est toujours un sur les valeurs normalisées, vous avez un bit supplémentaire caché).

longueur Exponent:

Myfloat a = 1.0; 
int max = 0, 
    min = 0; 

while (true) { 
a *= 2.0; 
if (a != NaN && a != Infinity && whatever) // depends on system 
    max++; 
else 
    break; 
} 

a = 1.0; 
while (true) { 
a *= 0.5; 
if (a != 0.0) 
    min--; 
else 
    break; 
} 

Vous décalez 1.0 vers la gauche ou vers la droite jusqu'à ce que vous appuyez sur le haut ou le bas. Normalement, la plage d'exp est -(max+1) - max.

Si min est inférieur à -(max+1), vous avez (sous forme de flottants et de doubles) des sous-normales. Les valeurs normalement positives et négatives sont symétriques (avec peut-être un décalage), mais vous pouvez ajuster le test en ajoutant des valeurs négatives.