Подтвердить что ты не робот

Учитывая r ^ 2, существует ли эффективный способ вычисления r ^ 3?

double r2 = dx * dx + dy * dy;
double r3 = r2 * sqrt(r2);

Можно ли заменить вторую строку чем-то быстрее? Что-то, что не связано с sqrt?

4b9b3361

Ответ 1

Я думаю, что другой способ взглянуть на ваш вопрос будет "как вычислить (или приблизительный) sqrt (n)". Оттуда ваш вопрос будет тривиальным (n * sqrt (n)). Конечно, вам нужно будет определить, сколько ошибок вы могли бы прожить. В Википедии есть много вариантов:

http://en.wikipedia.org/wiki/Methods_of_computing_square_roots

Ответ 2

Как насчет

double r3 = pow(r2,1.5);

Если sqrt реализован как частный случай pow, это спасет вас от умножения. Не так много в великой схеме разума!

Если вы действительно ищете большую эффективность, подумайте, действительно ли вам нужно r ^ 3. Если, например, вы только проверяете его (или что-то, полученное из него), чтобы узнать, превышает ли он определенный порог, тогда вместо теста r2, например,

const double r3_threshold = 9;

//don't do this
if (r3 > r3_threshold)
    ....

//do do this
const double r2_threshold = pow(r3_threshold,2./3.); 
if (r2 > r2_threshold)
    ....

Таким образом, pow будет вызываться только один раз, возможно даже во время компиляции.

РЕДАКТИРОВАТЬ Если вам нужно каждый раз пересчитывать порог, я думаю, что ответ, касающийся Q_rsqrt, стоит посмотреть и, вероятно, заслуживает того, чтобы опередить этот

Ответ 3

Используйте быстрый обратный sqrt (воспользуйтесь функцией Q_rsqrt).

У вас есть:

float r2;
// ... r2 gets a value
float invsqrt = Q_rsqrt(r2);
float r3 = r2*r2*invsqrt; // x*x/sqrt(x) = x*sqrt(x)

ПРИМЕЧАНИЕ. Для типов double существует константа типа 0x5f3759df, которая может помочь вам написать функцию, которая обрабатывает также типы данных double.

LATER EDIT: Похоже, что этот метод уже обсуждался здесь.

LATER EDIT2: Константа для double находилась в wikipedia ссылка:

Ломонт указал, что "магическое число" для 64-битного размера IEEE754 тип double - 0x5fe6ec85e7de30da, но на самом деле он близок к 0x5fe6eb50c7aa19f9.