我正在为Java中的exp,log和sqrt制作一些近似函数。关于指针如何工作我有点生疏 - 这个语法是否正确?
#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 :(得分:5)
一目了然,语法看起来是正确的(尽管编译器会告诉你比我们更快)。
然而,你在做什么看起来非常严峻。将double
重新解释为int
s取决于平台(认为字节顺序和sizeof
问题),并且还会违反“严格别名”规则。
答案 1 :(得分:2)
一般来说,这看起来非常错误,并为我提出了一些危险信号,但你可能没问题。
使用Java类型有所帮助。如果您要转换为int
,则在某些计算机上会出现问题,因为ints
可能是32位或64位。使用jint
,它应该始终是32位,所以在这方面你是安全的。
我还不完全清楚你在尝试什么。例如,这一行:
*(1 + (jint * ) &p) = tmp;
你要说的是取p(双精度)的地址,把它当作Java整数地址,然后加一个。这意味着获取double的位置并将4个字节放入其中...将您放在IEEE encoded double的小数部分。
然后,您将该位置设置为tmp中的值...这是一个整数而不是IEEE编码。
除非你通过直接操纵双重位来做某事incredibly clever,否则你所做的将会产生毫无意义的结果。