之前看了一篇描述神奇sqrt函数的文章,因此很好奇java是怎么实现sqrt的。
然后闲的无聊跟踪了一下Math.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
int main(int argc, char ** argv) int JNICALL JavaMain(void * _args)