Math.sqrt가 StrictMath.sqrt (double a)를 호출한다는 것을 알고 있습니다. 나는 그것을 계산하는 데 사용 된 실제 코드를보고 싶습니다.Java의 Square Root 함수의 소스 코드는 어디에서 찾을 수 있습니까?
답변
OpenJDK에서 소스 코드를 다운로드하십시오.
정확히 모르겠지만 뉴튼의 알고리즘을 마지막 지점에서 찾을 수있을 것 같습니다.
UPD : 구체적인 구현은 구체적인 자바 머신에 달려 있다고합니다. Windows의 경우 표준 연산자 sqrt가있는 어셈블러 구현을 사용하고 있습니다
어셈블러 opcode는 OS에 의존하지 않으므로 Windows와 관련이 없습니다. 그러나 예, JVM은 C 소스의 다양한 주석에 설명 된대로 기본 명령어를 선호합니다. – Joey
JDK를 설치하면 표준 라이브러리의 소스 코드가 src.zip
안에 있습니다.
public static native double sqrt(double a);
은 그래서 정말 그냥 기본 전화 그리고 자바에 의해 다른 플랫폼에서 다르게 구현 될 수 있습니다 다음과 같이 StrictMath.sqrt(double)
이 구현 이것은하지만, StrictMath
당신을 도움이되지 않습니다.
그러나 StrictMath
상태의 문서로 :
는 Java 프로그램의 이식성을 유지하기 위해이 패키지에있는 숫자의 일부 기능의 정의는, 기존의 알고리즘과 같은 결과를내는 것이 요구되고 있습니다. 이 알고리즘은 잘 알려진 네트워크 라이브러리
netlib
에서 "Freely Distributable Math Library"패키지 fdlibm으로 구할 수 있습니다. C 프로그래밍 언어로 작성된 이러한 알고리즘은 Java 부동 소수점 산술 규칙에 따라 모든 부동 소수점 연산으로 실행되는 것으로 이해해야합니다.Java math 라이브러리는 fdlibm 버전 5.3과 관련하여 정의됩니다. fdlibm이 acos와 같은 함수에 대해 둘 이상의 정의를 제공하는 경우, "IEEE 754 core function"버전을 사용하십시오 (이름이 문자 e로 시작하는 파일에 있음). fdlibm 의미를 필요로하는 메소드는 sin, cos, tan, asin, acos, atan, exp, log, log10, cbrt, atan2, pow, sinh, cosh, tanh, hypot, expm1 및 log1p입니다.
따라서 fdlibm
소스의 해당 버전을 찾으면 Java에서 사용되는 정확한 구현을 찾을 수 있습니다 (여기에서 사양에서 필수). 내가 OpenJDK 주위에 거짓말을해야하는 일이 있기 때문에
fdlibm
에 의해 사용되는 구현은 여기 구현을 보여주지,
static const double one = 1.0, tiny=1.0e-300;
double z;
int sign = (int) 0x80000000;
unsigned r, t1, s1, ix1, q1;
int ix0, s0, q, m, t, i;
ix0 = __HI(x); /* high word of x */
ix1 = __LO(x); /* low word of x */
/* take care of Inf and NaN */
if ((ix0 & 0x7ff00000) == 0x7ff00000) {
return x*x+x; /* sqrt(NaN) = NaN,
sqrt(+inf) = +inf,
sqrt(-inf) = sNaN */
}
/* take care of zero */
if (ix0 <= 0) {
if (((ix0&(~sign)) | ix1) == 0) {
return x; /* sqrt(+-0) = +-0 */
} else if (ix0 < 0) {
return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
}
}
/* normalize x */
m = (ix0 >> 20);
if (m == 0) { /* subnormal x */
while (ix0==0) {
m -= 21;
ix0 |= (ix1 >> 11); ix1 <<= 21;
}
for (i=0; (ix0&0x00100000)==0; i++) {
ix0 <<= 1;
}
m -= i-1;
ix0 |= (ix1 >> (32-i));
ix1 <<= i;
}
m -= 1023; /* unbias exponent */
ix0 = (ix0&0x000fffff)|0x00100000;
if (m&1) { /* odd m, double x to make it even */
ix0 += ix0 + ((ix1&sign) >> 31);
ix1 += ix1;
}
m >>= 1; /* m = [m/2] */
/* generate sqrt(x) bit by bit */
ix0 += ix0 + ((ix1 & sign)>>31);
ix1 += ix1;
q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */
r = 0x00200000; /* r = moving bit from right to left */
while (r != 0) {
t = s0 + r;
if (t <= ix0) {
s0 = t+r;
ix0 -= t;
q += r;
}
ix0 += ix0 + ((ix1&sign)>>31);
ix1 += ix1;
r>>=1;
}
r = sign;
while (r != 0) {
t1 = s1+r;
t = s0;
if ((t<ix0) || ((t == ix0) && (t1 <= ix1))) {
s1 = t1+r;
if (((t1&sign) == sign) && (s1 & sign) == 0) {
s0 += 1;
}
ix0 -= t;
if (ix1 < t1) {
ix0 -= 1;
}
ix1 -= t1;
q1 += r;
}
ix0 += ix0 + ((ix1&sign) >> 31);
ix1 += ix1;
r >>= 1;
}
/* use floating add to find out rounding direction */
if((ix0 | ix1) != 0) {
z = one - tiny; /* trigger inexact flag */
if (z >= one) {
z = one+tiny;
if (q1 == (unsigned) 0xffffffff) {
q1=0;
q += 1;
}
} else if (z > one) {
if (q1 == (unsigned) 0xfffffffe) {
q+=1;
}
q1+=2;
} else
q1 += (q1&1);
}
}
ix0 = (q>>1) + 0x3fe00000;
ix1 = q 1>> 1;
if ((q&1) == 1) ix1 |= sign;
ix0 += (m <<20);
__HI(z) = ix0;
__LO(z) = ix1;
return z;
음. 그것은 거의 너무 단순합니다 :-) –
저는 이것이 가변 길이 루프없이 어떻게 구현되는지 이해하지 못합니다. LOL. 이것에 대한 설명을 어디에서 찾을 수 있는지 알고 있습니까? –
@GershomMaes : 수학 StackExchange 사이트 중 하나에서 알고리즘이 어떻게 작동하는지 물어볼 것입니다. 코멘트는 질문을위한 것이 아닙니다. – Joey
입니다. JDK에서
/SRC/주/기본/자바/랭/StrictMath.c :
JNIEXPORT jdouble JNICALL
Java_java_lang_StrictMath_sqrt(JNIEnv *env, jclass unused, jdouble d)
{
return (jdouble) jsqrt((double)d);
}
jsqrt
는 JDK에 sqrt
로 정의됩니다/SRC/주/기본/자바/랭/fdlibm/SRC/w_sqrt.c (이름이 전처리를 통해 변경) :
#ifdef __STDC__
double sqrt(double x) /* wrapper sqrt */
#else
double sqrt(x) /* wrapper sqrt */
double x;
#endif
{
#ifdef _IEEE_LIBM
return __ieee754_sqrt(x);
#else
double z;
z = __ieee754_sqrt(x);
if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
if(x<0.0) {
return __kernel_standard(x,x,26); /* sqrt(negative) */
} else
return z;
#endif
}
그리고 __ieee754_sqrt
는 JDK에 정의되어/SRC/주/기본/자바/랭/fdlibm/SRC/e_sqrt.c :
#ifdef __STDC__
static const double one = 1.0, tiny=1.0e-300;
#else
static double one = 1.0, tiny=1.0e-300;
#endif
#ifdef __STDC__
double __ieee754_sqrt(double x)
#else
double __ieee754_sqrt(x)
double x;
#endif
{
double z;
int sign = (int)0x80000000;
unsigned r,t1,s1,ix1,q1;
int ix0,s0,q,m,t,i;
ix0 = __HI(x); /* high word of x */
ix1 = __LO(x); /* low word of x */
/* take care of Inf and NaN */
if((ix0&0x7ff00000)==0x7ff00000) {
return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
sqrt(-inf)=sNaN */
}
/* take care of zero */
if(ix0<=0) {
if(((ix0&(~sign))|ix1)==0) return x;/* sqrt(+-0) = +-0 */
else if(ix0<0)
return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
}
/* normalize x */
m = (ix0>>20);
if(m==0) { /* subnormal x */
while(ix0==0) {
m -= 21;
ix0 |= (ix1>>11); ix1 <<= 21;
}
for(i=0;(ix0&0x00100000)==0;i++) ix0<<=1;
m -= i-1;
ix0 |= (ix1>>(32-i));
ix1 <<= i;
}
m -= 1023; /* unbias exponent */
ix0 = (ix0&0x000fffff)|0x00100000;
if(m&1){ /* odd m, double x to make it even */
ix0 += ix0 + ((ix1&sign)>>31);
ix1 += ix1;
}
m >>= 1; /* m = [m/2] */
/* generate sqrt(x) bit by bit */
ix0 += ix0 + ((ix1&sign)>>31);
ix1 += ix1;
q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */
r = 0x00200000; /* r = moving bit from right to left */
while(r!=0) {
t = s0+r;
if(t<=ix0) {
s0 = t+r;
ix0 -= t;
q += r;
}
ix0 += ix0 + ((ix1&sign)>>31);
ix1 += ix1;
r>>=1;
}
r = sign;
while(r!=0) {
t1 = s1+r;
t = s0;
if((t<ix0)||((t==ix0)&&(t1<=ix1))) {
s1 = t1+r;
if(((t1&sign)==sign)&&(s1&sign)==0) s0 += 1;
ix0 -= t;
if (ix1 < t1) ix0 -= 1;
ix1 -= t1;
q1 += r;
}
ix0 += ix0 + ((ix1&sign)>>31);
ix1 += ix1;
r>>=1;
}
/* use floating add to find out rounding direction */
if((ix0|ix1)!=0) {
z = one-tiny; /* trigger inexact flag */
if (z>=one) {
z = one+tiny;
if (q1==(unsigned)0xffffffff) { q1=0; q += 1;}
else if (z>one) {
if (q1==(unsigned)0xfffffffe) q+=1;
q1+=2;
} else
q1 += (q1&1);
}
}
ix0 = (q>>1)+0x3fe00000;
ix1 = q1>>1;
if ((q&1)==1) ix1 |= sign;
ix0 += (m <<20);
__HI(z) = ix0;
__LO(z) = ix1;
return z;
}
사용 된 방법을 설명하는 파일에 많은 의견이 있으며, (반자동) 간결성을 위해 생략했습니다. Here's the file in Mercurial (올바른 방법이 연결되기를 바랍니다.)
+ hg 소스에 대한 링크 1 개 – Will
- 1. itertools.combinations() 함수의 소스 코드는 어디에서 찾을 수 있습니까?
- 2. ldconfig의 소스 코드는 어디에서 찾을 수 있습니까?
- 3. httpsURLConnection 소스 코드는 어디에서 찾을 수 있습니까?
- 4. JDK에서 네이티브 코드는 어디에서 찾을 수 있습니까?
- 5. 파이썬의 hash() 함수의 소스 또는 알고리즘은 어디에서 찾을 수 있습니까?
- 6. 카메라 안드로이드 API의 원시 소스 코드는 어디에서 찾을 수 있습니까?
- 7. NServicebus 2.1 소스 코드는 어디에서 찾을 수 있습니까?
- 8. Java 데이터 구조의 소스 코드는 어디에서 찾을 수 있습니까?
- 9. Redhat의 내쉬 유틸리티에 대한 소스 코드는 어디에서 찾을 수 있습니까?
- 10. 수학 곡선을 시각화하기위한 C# 소스 코드는 어디에서 찾을 수 있습니까?
- 11. RSA의 공식 소스 코드는 어디에서 찾을 수 있습니까?
- 12. Google 토크 Android 클라이언트 소스 코드는 어디에서 찾을 수 있습니까?
- 13. 특정 컴파일러를 벤치마킹하기위한 좋은 소스 코드는 어디에서 찾을 수 있습니까?
- 14. BLAS 예제 코드는 어디에서 찾을 수 있습니까?
- 15. 안드로이드의 앱 코드는 어디에서 찾을 수 있습니까?
- 16. 어디에서 FlexMonkium 소스 코드를 찾을 수 있습니까?
- 17. BitTorrent 소스 코드를 어디에서 찾을 수 있습니까?
- 18. Android : 네이티브 브라우저 앱의 코드는 어디에서 찾을 수 있습니까?
- 19. iPhone에서 사진에 효과를 추가하는 샘플 코드는 어디에서 찾을 수 있습니까?
- 20. ocaml에서 표준 라이브러리의 소스 코드는 어디에 있습니까?
- 21. ContactsListActivity는 어디에서 찾을 수 있습니까?
- 22. 이 함수의 기본 구현은 어디에서 찾을 수 있습니까?
- 23. Android : Google 뮤직 앱 코드는 어디에서 찾을 수 있습니까?
- 24. iPhone 응용 프로그램의 샘플 코드는 어디에서 찾을 수 있습니까?
- 25. 애플리케이션 내에서 iAd를 통합하기위한 샘플 코드는 어디에서 찾을 수 있습니까?
- 26. 안드로이드 용 Gmail, 페이스 북 및 트위터 앱의 소스 코드는 어디에서 찾을 수 있습니까? 오픈 소스인가?
- 27. JBoss AS 5 기본 예외 처리 JSP의 소스 코드는 어디에서 찾을 수 있습니까?
- 28. Objective-C 2.0 런타임의 최신 소스 코드는 어디에서 찾을 수 있습니까?
- 29. 어디에서 Castle.MicroKernel.dll을 찾을 수 있습니까?
- 30. 어디에서 GladeGen을 찾을 수 있습니까?
나는 인텔이 sqrt 명령을 가지고 있다고 생각했다. 사실이 아닌가? – Marichyasana