«1. Обзор

Попытка найти n-й корень в Java с помощью pow() в некоторых случаях неверна. Причина этого в том, что двойные числа могут потерять точность по пути. Следовательно, нам может понадобиться отшлифовать результат, чтобы справиться с этими случаями.

2. Проблема

Предположим, мы хотим вычислить корень N как:

base = 125, exponent = 3

Другими словами, какое число в степени 3 равно 125?

При условии, что n-й корень числа x равен числу x в степени 1/n. Итак, мы переводим наше уравнение в:

N-th root = Math.pow(125, 1/3)

Результат равен 4,999999999999999. А 4,999999999999999 в степени 3 — это не 125. Так как же нам это исправить?

3. Правильное вычисление N-го корня

Решение вышеприведенной проблемы в основном представляет собой математический обходной путь, и он настолько прост, насколько это возможно. Хорошо известно, что n-й корень числа x равен числу x в степени 1/n.

Есть несколько способов использовать приведенное выше уравнение. Во-первых, мы можем использовать BigDecimal и реализовать нашу версию метода Ньютона-Рафсона. Во-вторых, мы можем округлить результат до ближайшего числа и, наконец, мы можем определить погрешность, при которой результаты будут приемлемыми. Мы сосредоточимся на последних двух подходах.

3.1. Округление

Теперь мы будем использовать округление для решения нашей задачи. Давайте воспользуемся нашим предыдущим примером и посмотрим, как мы можем получить правильный результат:

public void whenBaseIs125AndNIs3_thenNthIs5() {
    double nth = Math.round(Math.pow(125, 1.0 / 3.0));
    assertEquals(5, nth, 0);
}

3.2. Погрешность

Этот подход очень похож на описанный выше. Нам просто нужно определить допустимую погрешность, предположим, 0,00001:

public void whenBaseIs625AndNIs4_thenNthIs5() {
    double nth = Math.pow(625, 1.0 / 4.0);
    assertEquals(5, nth, 0.00001);
}

Тест доказывает, что наши методы правильно вычисляют корень n-й степени.

4. Заключение

Как разработчики, мы должны понимать типы данных и их поведение. Описанные выше математические методы работают очень хорошо с довольно хорошей точностью. Вы можете выбрать тот, который лучше подходит для вашего варианта использования. Код решения выше можно найти на GitHub.