2012-10-27 2 views
2
double value = 02369.000133699;//acutally stored as 2369.000133698999900 
const std::uint32_t left = std::uint32_t(std::abs(value) < 1 ? 1: (1 + std::log10(std::abs(value)))); 

std::ostringstream out; 
out << std::setprecision(std::numeric_limits<T>::digits10 - left) << std::fixed << value; 
std::string str = out.str(); //str = "2369.00013369900" 

std::ostringstream out2; 
out2 << std::setprecision(std::numeric_limits<T>::digits10) << std::fixed << value; 
std::string str2 = out2.str(); // str2 = "2369.000133698999900" 

Je me demande comment std :: stringstream/precision fonctionne pour le formatage du nombre à virgule flottante. Il semble que si l'argument de précision est supérieure à 16 nombre moins de chiffres non-fractions, cela a conduit à une mise en forme de la forme "2369.000133698999900" au lieu d'une « belle » "2369.00013369900"stringstream setprecision et formatage à virgule flottante

comment std::stringstream savent que 8999900 doit être reprendre une 9 même si je ne "t lui dire de faire l'arrondissement sur la 8 (comme en passant 12 comme argument à la fonction setprecision)? mais ne le font pas à l'argument supérieur à 12

Répondre

1

Mise en forme Floating Points binaires comme valeurs décimales est assez Le problème sous-jacent est que les points flottants binaires ne peuvent pas représenter des valeurs décimales exactes. Ely. Même un nombre simple comme 0,1 ne peut pas être représenté exactement en utilisant des points flottants binaires. Autrement dit, la valeur réelle représentée est légèrement différente. Lors de l'utilisation d'algorithmes intelligents pour la lecture ("Bellerophon") et le formatage ("Dragon4": les noms des articles originaux et les améliorations des deux algorithmes utilisés dans la pratique), les nombres décimaux sont utilisés pour transporter les valeurs décimales. Cependant, en demandant à l'algorithme de mettre en forme plus de chiffres décimaux que ce qu'il peut réellement contenir, c'est-à-dire plus de std::numeric_limits<T>::digits10, il le fera heureusement, révélant [partiellement] la valeur qu'il est réellement en train de stocker. L'algorithme de formatage ("Dragon4") suppose que la valeur donnée est la valeur la plus proche de l'original représentable avec le type à virgule flottante. Il utilise cette information avec une estimation d'erreur pour la position actuelle afin de déterminer les chiffres corrects. L'algorithme lui-même est non-trivial et je n'ai pas entièrement compris comment cela fonctionne. Il est décrit dans l'article "Comment imprimer les nombres à virgule flottante avec précision" par Guy L. Steele Jr. et Jon L. White.