0

標準ライブラリのgcc実装のバグとして以下を報告すべきかしら。

すべての符号なし整数について、整数の実際の平方根とi比較すると、変換は常に良好な結果をもたらします。int(std::sqrt(i))私たちが同じことをするなら、そうではありstd::cbrtません:

// Problem of rounding of std::cbrt for i from 0 to 100 million
// i, exact cbrt(i), result of int(std::cbrt(i))
2197, 13, 12
17576, 26, 25
24389, 29, 28
140608, 52, 51
185193, 57, 56
195112, 58, 57
226981, 61, 60
1092727, 103, 102
1124864, 104, 103
1442897, 113, 112
1481544, 114, 113
1560896, 116, 115
1685159, 119, 118
1815848, 122, 121
8741816, 206, 205
8869743, 207, 206
8998912, 208, 207
9393931, 211, 210
9938375, 215, 214
11543176, 226, 225
11852352, 228, 227
12487168, 232, 231
12649337, 233, 232
13481272, 238, 237
13651919, 239, 238
14348907, 243, 242
14526784, 244, 243
14706125, 245, 244
69426531, 411, 410
69934528, 412, 411
70957944, 414, 413
71991296, 416, 415
72511713, 417, 416
73560059, 419, 418
74618461, 421, 420
75151448, 422, 421
79507000, 430, 429
88121125, 445, 444
89314623, 447, 446
91733851, 451, 450
92345408, 452, 451
92959677, 453, 452
94818816, 456, 455
99897344, 464, 463 

それは欠陥として報告されるべきだと思いますか?

4

1 に答える 1

2

std::cbrt浮動小数点型 (float、double など) を返しますが、それをint. このような変換では、0.9999 が 0 になるなど、丸めではなく切り捨てが行われます。2197 の立方根が整数であることは論理的に思えるかもしれませんが、浮動小数点型は 2 進数で格納されるため、常に 10 進数を完全に表現できるとは限りません。 、およびそのような不正確さは、実行する計算中に伝播する可能性がありstd::cbrtます。たとえば、std::cbrt(2197) == 12.99999(私のコンパイラはそれをサポートしていないので、実際の値を確認できません)、それを に変換することでint、値を 12 に切り捨てます。

コードを修正するには、std::cbrt(i)に変換する前にの結果を丸めますintその方法については、この質問を参照 してください。

于 2013-01-14T01:42:19.843 に答える