Почему функция pow так вычисляет кубический корень?
Всем привет!
Совершенно случайно недавно столкнулся с тем, что функция pow(125, 1.0/3.0) в результате дает ответ 4.99999999999999991, а не 5. При этом встроенная функция cbrt даёт правильный ответ. Просто теперь переживаю насчет остальных корней.
Кто-нибудь может объяснить, почему так происходит (хотя я догадываюсь, что возможно дело в результате деления 1 на 3), а главное -- что с этим делать в других степенях (например, 1/7)?
Спасибо!
P.S. А вот из 27 кубический корень находится правильно
Для вычислений используются операции в математическом сопроцессоре, а там все числа в виде ±MeX (±M*10^X), где M - число от 1 до 10, хранимое в двоичном виде и имеющее от 19 до 20 знаков в пересчёте в десятичную систему. Мы можем получить погрешность при самых тривиальных операциях. Например, 5e15 + 5e-15 = 5000000000000000.0 (то есть по сути первое слагаемое), потому что для отражения разницы нужна точность в 30 знаков. Нам хватало точности для исходных чисел, но перестало хватать для суммы.
Чтобы вычислить степень точно, нужно в первую очередь не потерять в точности при вычислении 1/3, далее понять, что 0.333333333333333*3 это не 0.999999999999 а 1, а потом вместо возведения в степень применить более эффективную формулу вычисления кубического корня. В идеале использовать какие-нибудь библиотеки символьных вычислений, они медленные, но могут, например, уметь хранить 1/3 как дробь, а не как вычисленное с некоторой точностью число до какого-то знака.