?
之前看了一篇描述神奇sqrt函数的文章,因此很好奇java是怎么实现sqrt的。
?
public static double sqrt(double a) { return StrictMath.sqrt(a); }
?
然后:
在StrictMath里
public static native double sqrt(double a);
?
?
?
说明sqrt是一个native的实现。
?
从StrictMath的类说明中可以得知,这是调用了一个
?
Freely Distributable Math?Library?fdlibm.tar
?
找了一下,在jdk/share/native/java/lang/fdlibm/中可以发现相应的H文件和.c文件
?
打开e_sqrt.c可以看懂sqrt函数的真正定义
原来是用最经典的迭代的方法计算的,显然要比John Carmack(雷神之锤的作者)所用的
magic numbe r? 0x5f3759df ?的方法要慢不少。。。。。。。
?
顺便再来看看java是怎么把这个fdlibm弄进来的。
?
jdk文件夹下有很多 主要:java/jre/lib/amd64
?
其中libjava最可疑 (windows下貌似是java.dll?)
?
?
使用nm查看so文件?用grep看 sqrt所在位置
?
?
果然是它:
?
0000000000013a90 T Java_java_lang_StrictMath_IEEEremainder
00000000000139e0 T Java_java_lang_StrictMath_acos
00000000000139d0 T Java_java_lang_StrictMath_asin
00000000000139f0 T Java_java_lang_StrictMath_atan
0000000000013a70 T Java_java_lang_StrictMath_atan2
0000000000013a40 T Java_java_lang_StrictMath_cbrt
0000000000013a50 T Java_java_lang_StrictMath_ceil
00000000000139a0 T Java_java_lang_StrictMath_cos
0000000000013aa0 T Java_java_lang_StrictMath_cosh
0000000000013a00 T Java_java_lang_StrictMath_exp
0000000000013af0 T Java_java_lang_StrictMath_expm1
0000000000013a60 T Java_java_lang_StrictMath_floor
0000000000013ad0 T Java_java_lang_StrictMath_hypot
0000000000013a10 T Java_java_lang_StrictMath_log
0000000000013a20 T Java_java_lang_StrictMath_log10
0000000000013ae0 T Java_java_lang_StrictMath_log1p
0000000000013a80 T Java_java_lang_StrictMath_pow
00000000000139b0 T Java_java_lang_StrictMath_sin
0000000000013ab0 T Java_java_lang_StrictMath_sinh
0000000000013a30 T Java_java_lang_StrictMath_sqrt
00000000000139c0 T Java_java_lang_StrictMath_tan
0000000000013ac0 T Java_java_lang_StrictMath_tanh