Как реализовать «быстрый обратный квадратный корень» в Java?
7302 просмотра
2 ответа
Я слышал о «быстром обратном квадратном корне», который обсуждался здесь , и я хотел включить его в свою Java-программу (только для исследовательских целей, поэтому не обращайте внимания на то, что нативные библиотеки быстрее).
Я смотрел на код, и код на C напрямую преобразует float
в int
с некоторой магией указатель C. Если вы попытаетесь сделать это в Java с приведением типов, это не сработает: java усекает число с плавающей запятой (как и следовало ожидать), и вы не можете получить указатель на примитив (как вы можете в C). Так как ты это делаешь?
Ответы (2)
20 плюса
Не забудьте сравнить свой код перед использованием.
Если окажется, что он вам не нужен или он медленнее в используемой архитектуре ЦП, то лучше обойтись без этого тупого кода в вашем проекте.
У библиотек Java есть способ добраться от числа с плавающей точкой до необработанных битов.
Как видно из Javadoc для java.lang.Float
( http://docs.oracle.com/javase/6/docs/api/java/lang/Float.html ), у нас также есть floatToIntBits
функция intBitsToFloat
.
Это означает, что мы можем написать «быстрый обратный квадратный корень» в Java следующим образом:
public static float invSqrt(float x) {
float xhalf = 0.5f * x;
int i = Float.floatToIntBits(x);
i = 0x5f3759df - (i >> 1);
x = Float.intBitsToFloat(i);
x *= (1.5f - xhalf * x * x);
return x;
}
Вот версия для пар:
public static double invSqrt(double x) {
double xhalf = 0.5d * x;
long i = Double.doubleToLongBits(x);
i = 0x5fe6ec85e7de30daL - (i >> 1);
x = Double.longBitsToDouble(i);
x *= (1.5d - xhalf * x * x);
return x;
}
Источник: http://www.actionscript.org/forums/showthread.php3?t=142537
Автор: Riking Размещён: 16.07.2012 10:125 плюса
Для ответа Рикинга , даже двойное число может вернуть что-то вроде 0,9983227945440889 для квадратного корня из одного.
Чтобы повысить точность, вы можете использовать эту версию, которую я сделал:
public static double Q_rsqrt(double number){
double x = number;
double xhalf = 0.5d*x;
long i = Double.doubleToLongBits(x);
i = 0x5fe6ec85e7de30daL - (i>>1);
x = Double.longBitsToDouble(i);
for(int it = 0; it < 4; it++){
x = x*(1.5d - xhalf*x*x);
}
x *= number;
return x;
}
Вы можете отредактировать, как долго завершается цикл for, как вы хотите, но 4 раза, кажется, снизили его до максимальной точности в два раза. Если вы хотите идеальной точности (или если длинные строки десятичных знаков там, где они не должны вас беспокоить), используйте эту версию.
Автор: Zeusoflightning125 Размещён: 03.01.2014 05:34Вопросы из категории :
- java В чем разница между int и Integer в Java и C #?
- java Как я могу определить IP моего маршрутизатора / шлюза в Java?
- java Каков наилучший способ проверки XML-файла по сравнению с XSD-файлом?
- java Как округлить результат целочисленного деления?
- java Преобразование списка <Integer> в список <String>
- java Почему я не могу объявить статические методы в интерфейсе?
- floating-point Преобразовать десятичную в двойную?
- floating-point Как вручную проанализировать число с плавающей запятой из строки
- floating-point Плавающая / двойная точность в режимах отладки / выпуска
- floating-point Сохраняйте точность с двойным в Java
- floating-point Насколько детерминистична погрешность с плавающей запятой?
- floating-point Как проверить, является ли строка числом (с плавающей запятой)?
- square-root Looking for an efficient integer square root algorithm for ARM Thumb2
- square-root Как реализована функция квадратного корня?
- square-root Как найти квадратный корень Java BigInteger?
- square-root квадратный корень символ / символ
- square-root Как включить знак квадратного корня, как показано на следующем изображении в Android?
- square-root Calculate Nth root with integer arithmetic