Я ищу быстрый код для 64-битных (без знаковых) корней куба. (Я использую C и компилирую с gcc, но я предполагаю, что большая часть требуемой работы будет агностикой языка и компилятора.) Я буду обозначать путем ulong 64-битное целое число без знака.
Учитывая вход n, я требую (интегральное) возвращаемое значение r таким, чтобы
r * r * r <= n && n < (r + 1) * (r + 1) * (r + 1)
То есть, я хочу, чтобы корень куба n, закругленный. Основной код, например
return (ulong)pow(n, 1.0/3);
неверно из-за округления к концу диапазона. Непродуманный код, например
ulong
cuberoot(ulong n)
{
ulong ret = pow(n + 0.5, 1.0/3);
if (n < 100000000000001ULL)
return ret;
if (n >= 18446724184312856125ULL)
return 2642245ULL;
if (ret * ret * ret > n) {
ret--;
while (ret * ret * ret > n)
ret--;
return ret;
}
while ((ret + 1) * (ret + 1) * (ret + 1) <= n)
ret++;
return ret;
}
дает правильный результат, но медленнее, чем это должно быть.
Этот код предназначен для математической библиотеки, и он будет вызываться много раз из различных функций. Скорость важна, но вы не можете рассчитывать на теплый кеш (так что предложения, такие как двоичный поиск в размере 2,642,245).
Для сравнения здесь приведен код, который правильно вычисляет квадратный корень целого.
ulong squareroot(ulong a) {
ulong x = (ulong)sqrt((double)a);
if (x > 0xFFFFFFFF || x*x > a)
x--;
return x;
}