Ошибка округления std :: cbrt?

Интересно, следует ли сообщать о следующем как об ошибке в реализации стандартной библиотеки 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

Считаете ли вы, что это следует указывать как дефект?

-1

Решение

std::cbrt возвращает тип с плавающей точкой (float, double и т. д.), но вы конвертируете его в int, Такие преобразования усечены, а не округлены, например 0,9999 становится 0. Хотя может показаться логичным, что корень куба 2197 является целым числом, из-за того, что типы с плавающей запятой хранятся в двоичном формате, не всегда возможно точно представить десятичное число, и такие неточности, вероятно, распространяться во время расчетов, std::cbrt выполняет. Если, например, std::cbrt(2197) == 12.99999 (мой компилятор не поддерживает его, поэтому я не могу проверить реальное значение), затем преобразовав его в int Вы усекаете значение до 12.

Чтобы исправить свой код, округлите результат std::cbrt(i) прежде чем преобразовать его в int, Увидеть этот вопрос за идею, как это сделать.

2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector