2010-09-09 84 views
0

我正在为java中的C,exp,log和sqrt做一些近似函数。我对指针如何工作有些生疏 - 这个语法是否正确?C近似函数

#include <math.h> 
#include "QDMath.h" 

JNIEXPORT jdouble JNICALL Java_QDMath_exp 
    (JNIEnv *env, jclass class, jdouble val) 
{ 
    jint tmp = (jint) (1512775 * val + 1072632447); 
    jdouble p = 0.0; 
    *(1 + (jint *) &p) = tmp; 
    return p; 
} 

JNIEXPORT jdouble JNICALL Java_QDMath_log 
    (JNIEnv *env, jclass class, jdouble val) 
{ 
    jint tmp = (*(1 + (jint *) &val)); 
    jdouble p = ((jdouble) tmp - 1072632447)/1512775; 
    return p; 
} 

JNIEXPORT jdouble JNICALL Java_QDMath_sqrt 
    (JNIEnv *env, jclass class, jdouble val) 
{ 
    jlong tmp = ((*(jlong *) &val) - 1065353216)>>1; 
    return *(jdouble *) &tmp; 
} 
+0

谢谢,你打败我重新格式化 – ShahQermez 2010-09-09 20:29:19

回答

5

一眼看去,语法看起来正确(尽管编译器会告诉你比我们更快)。

但是,你在做什么看起来相当严峻。重新解释double s为int s是平台相关的(考虑endianness和sizeof问题),并且也会落入“严格别名”规则的犯规。

+0

此外,其中一些计算可能会产生浮点值太大,以保持int,从而调用未定义的行为。这些功能是非常具体的实现,假设它们都可以工作。 – 2010-09-09 21:20:47

+0

http://cnl.salk.edu/~schraudo/pubs/Schraudolph99.pdf是exp和日志函数的来源 http://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Approximations_that_depend_on_IEEE_representation explain sqrt – ShahQermez 2010-09-09 22:28:36

+3

我会亲自用一些积极的编译时间断言来保护所有这样的代码,以验证目标浮点数是否具有他们所依赖的表示。大恐怖的警卫会提醒未来的代码审查人员,这是神奇的,而且你确实考虑过魔法的效果。请记住,从现在开始五年后,评论者可能就是你。另外,一些评论中的内容指出了解释如何以及为什么会起作用的参考。你未来的自我将不太可能想要时间旅行,以这种方式击败你的头脑;-) – RBerteig 2010-09-10 03:02:41

2

一般来说,这看起来很不对,并为我提出了一些红旗,但你可能没问题。

使用Java类型是有帮助的。如果您投射到int,则在某些机器上会出现问题,因为ints可能是32位或64位。使用jint,它应该始终是32位,所以在这方面你是安全的。

我还不完全清楚你正在尝试什么。例如,该行:

*(1 + (jint *) &p) = tmp; 

你所说的做的是把P的地址(双),把它当作一个Java的整数地址,然后添加一个到它。这将意味着采取加倍的位置,并看看4个字节......将您置于IEEE encoded double的小数部分。

然后,您将该位置设置为tmp中的值...这是一个整数,而不是IEEE编码的值。

除非您通过直接操作double的位来做某件事incredibly clever,否则您正在做的事情会产生无意义的结果。

+0

这种事情看起来很像老式的“逆平方根”技巧:http://en.wikipedia.org /维基/ Fast_inverse_square_root。严峻。 – 2010-09-09 21:11:11

+0

我的猜测是'jint'会是一个Java'int',它是四个字节。但是,我不知道任何指数和尾数都占用四个字节的格式(将符号位放在您将要到达的位置)。 – 2010-09-09 21:22:36

+0

jints上的良好调用...我忘记了JDK将确保这些调整大小以匹配固定的Java规范。我已经相应更新。 – 2010-09-09 22:15:30