double r2 = dx * dx + dy * dy;
double r3 = r2 * sqrt(r2);
Можно ли заменить вторую строку чем-то быстрее? Что-то, что не связано с sqrt
?
double r2 = dx * dx + dy * dy;
double r3 = r2 * sqrt(r2);
Можно ли заменить вторую строку чем-то быстрее? Что-то, что не связано с sqrt
?
Я думаю, что другой способ взглянуть на ваш вопрос будет "как вычислить (или приблизительный) sqrt (n)". Оттуда ваш вопрос будет тривиальным (n * sqrt (n)). Конечно, вам нужно будет определить, сколько ошибок вы могли бы прожить. В Википедии есть много вариантов:
http://en.wikipedia.org/wiki/Methods_of_computing_square_roots
Как насчет
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, стоит посмотреть и, вероятно, заслуживает того, чтобы опередить этот
Используйте быстрый обратный 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.