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"

std::stringstream/precision が浮動小数点数をフォーマットするためにどのように機能するのか疑問に思っています。精度引数が16非小数桁のマイナス数よりも優れている場合、これ"2369.000133698999900"は「ナイス」ではなくフォームのフォーマットにつながるようです"2369.00013369900"

(関数への引数として渡すなど)で丸めを行うように指示しなくても、それが1に再開する必要があることをどのようstd::stringstreamに知っていますか?しかし、12より大きい引数に対しては丸めを行わないでください89999009812setprecision

4

1 に答える 1

1

2 進浮動小数点を 10 進数値としてフォーマットするのは、かなり注意が必要です。根本的な問題は、2 進浮動小数点が 10 進数値を正確に表現できないことです。0.1 のような単純な数値でさえ、2 進浮動小数点を使用して正確に表すことはできません。つまり、表される実際の値はわずかに異なります。読み取り (「Bellerophon」) とフォーマット (「Dragon4」。これらは元の論文の名前であり、実際に使用される両方のアルゴリズムの改善があります) に巧妙なアルゴリズムを使用する場合、浮動小数点数を使用して 10 進数値を転送します。しかし、アルゴリズムが実際に保持できるよりも多くの 10 進数をフォーマットするように要求する場合、つまり よりも多くの 10 進数をフォーマットするようにアルゴリズムに要求すると、std::numeric_limits<T>::digits10実際に格納している値が [部分的に] 明らかになり、アルゴリズムは喜んでそうします。

フォーマット アルゴリズム ("Dragon4") は、指定された値が、浮動小数点型で表現可能な元の値に最も近い値であると想定します。この情報と現在位置の推定誤差を使用して、正しい数字を決定します。アルゴリズム自体は自明ではなく、それがどのように機能するかを完全には理解していません。これについては、Guy L. Steele Jr. と Jon L. White による論文「How to Print Floating-Point Numbers Accurately」で説明されています。

于 2012-10-27T23:21:55.630 に答える