线程中的数学函数返回错误的值,使用android ndk

时间:2014-06-20 11:25:03

标签: android c++ math android-ndk math.h

我在尝试将代码移植到Android NDK时出现问题,这在iOS上运行良好。 代码渲染3D模型并使用openGL ES 1.1,因此它使用标准c数学库(包括math.h)执行许多计算。

以下是用于测试异常的代码片段:

double e;
e = sqrt(25);
assert(e == 5);
e = sqrt(16);
assert(e == 4);
e = sqrt(9);
assert(e == 3);
e = sqrt(4);
assert(e == 2);
e = sqrt(1);
assert(e == 1);
e = sqrt(0);
assert(e == 0);

这些断言在任何地方工作都很好,而这个:

int vec[10] = {0, 1, 4, 9, 16, 25, 36, 49, 64, 81};
int res[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
double d;
for (int i=0; i<10; i++) {
    d = sqrt(vec[i]);
    assert(d == res[i]);
}

在主要线程以外的任何线程上崩溃。例如,它返回0.37500000008731149作为sqrt(0),这就是for循环中的第一个断言失败的原因。

似乎问题在于使用变量内容的计算,而不是硬编码值的计算。可能是关于不同线程上的内存映射的问题?我调试了它,并打印了vec [i]的值,但这些都是正确的。

数学库在不同的线程中使用时是否有任何问题?你能给我另一个解释,为什么这样做很奇怪?

编辑:我也看到了与其他数学函数相同的奇怪行为,例如pow()和sin()。另外,我也试过sqrtf和powf。他们似乎都给出了不同但又错误的价值观,而不是双重价值观。

2 个答案:

答案 0 :(得分:0)

d == res[i]

这是你的问题。除了你正在比较double和int并且不知道哪一个将被转换为其他类型的事实之外,你还要将浮点数与==运算符进行比较。 / p>

比较花车和双打并不是这样的,因为

4.00000000000001 == 4.0

将返回false,浮点运算并不完美,而sqrt(16)之类的东西可能不一定正好返回4。

不使用==运算符,而是使用这样的函数(如果编译的话,我还没有测试过)

bool AreEqual(double a, double b)
{
  return a < b + 0.00001 && a > b - 0.00001;
}

代替。

答案 1 :(得分:0)

我终于得出了一些关于如何“解决”这个问题的结论,尽管我有点失去了为什么这首先发生了。

我实际上正在编写一个链接到几个c ++库的应用程序,这是iOS和Android应用程序之间的通用代码。当在这些库中执行数学计算时,math会返回错误的值。我认为这不是线程问题,而是关于库和链接范围的问题。当我编译应用程序内的所有库时,问题就消失了,因为那些是另一个CPP源。但是,这不是最好的方法,因为打破了libs的模块化。我必须解决这个问题,但这将是一个非常不同的问题。