Квадратный корень в Java
Реализуя метод проверки числа на простоту, по следам нахождения простых чисел:
package ru.yamakarov.prime;
public class Sqrt {
boolean isPrime(int number) {
if (number == 1) {
return true;
}
double sqrt = Math.sqrt(number);
for (int i = 2; i < sqrt; i++) {
if (number % i == 0) {
return false;
}
}
return true;
}
}
Я стал разбираться, как работает Math.sqrt
.
Реализация – простая, java.lang.Math
делегирует работу java.lang.StrictMath
:
public static double sqrt(double a) {
return StrictMath.sqrt(a); // default impl. delegates to StrictMath
// Note that hardware sqrt instructions
// frequently can be directly used by JITs
// and should be much faster than doing
// Math.sqrt in software.
}
Комментарий про хардварные инструкции очень интересен и надо смотреть код jdk, чтобы разобраться, как они подставляются и на каком этапе.
В идее доступен лишь вызов нативного метода в java.lang.StrictMath
:
public static native double sqrt(double a);
Как следует из javadoc, реализация берется из библиотеки fdlibm. И там реализация устрашающая e_sqrt.c.
Я решил накидать свою для интереса. И методом половинного деления для натуральных чисел написал такую программульку:
package ru.yamakarov.sqrt;
/**
* Square root
*
*/
public class SquareRoot
{
public static void main( String[] args ) {
int n = 9;
double l = 0;
double h = n;
double r = 0;
while (h - l > 0.00000000000000001) {
System.out.println(h + " " + l + " " + r);
r = (h + l) / 2;
double r2 = r * r;
if ( r2 == n) {
break;
}
if ( r2 > n) {
h = r;
} else {
l = r;
}
}
System.out.println(r);
System.out.println(r * r);
System.out.println(Math.sqrt(n));
}
}
Она проще и короче, но боюсь работает адски долго.