线程中的数学函数返回错误的值,使用android ndk
math functions in thread returning wrong values, with android ndk
我在尝试将代码移植到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。
d == res[i]
这是你的问题。除了比较双精度型和整型并且不知道哪一个将被强制转换为另一个类型之外,还可以用==操作符比较浮点数。
浮点数和双精度数的比较不是这样的,因为
4.00000000000001 == 4.0
将返回false,浮点运算不是完美的,像sqrt(16)这样的运算不一定返回正好4。
不使用==操作符,而是使用如下函数(我还没有测试过它是否可以编译)
bool AreEqual(double a, double b)
{
return a < b + 0.00001 && a > b - 0.00001;
}
。
我终于得到了一些关于如何"解决"这个问题的结论,尽管我有点失去了为什么会发生这种情况。
我实际上正在编写一个链接到几个c++库的应用程序,这是iOS和Android应用程序之间的通用代码。当在这些库中执行数学计算时,数学返回那些错误的值。我相信这不是关于线程的问题,而是关于库和链接的作用域的问题。当我编译应用程序内的所有库时,问题消失了,因为这些是另一个CPP源。但是,这不是最好的方法,因为这会破坏库的模块化。我必须修正它,但那将是一个非常不同的问题。
- 在 constexpr 构造函数 (c++17) 中赋值到 const char * 在使用 Android NDK 时
- 在 Flutter 应用程序中使用 Android NDK 中的 AssetManager 类
- 如何在Qt中使用Android上的USB OTG串行接口?
- 使用 Android NDK 使用 clang++ 编译C++代码时对"_Unwind_Resume"的未定义引用
- 无法在"surface input"模式下使用 Android 平台的 MediaCodec 类
- 为什么当我的项目是使用 Android NDK r16 构建时,我会收到来自 Android NDK r11 的错误消息
- 使用 Android Studio 使用本机代码编译 apk 时,如何在链接处删除 libgnustl_static.
- 如何使用Android的双簧管/ AAudio从多个麦克风读取数据
- 使用 Android NDK 的 Azure 存储客户端库进行C++ (3.0.0)
- 使用 Android NDK 演示 printf 或 __android_log_print 漏洞
- 如何使用Android Studio 2.2.3调试外部本机库的C 源代码
- 为什么我们需要使用android工具链(或NDK)来编译在android应用程序上下文中运行的c/c++代码
- 使用Android NDK从字符串路径打开文件
- 如何使用Android构建的CMAKE GERTATOR-EXPEXPRYS生成Clang编译器标志
- 使用Android Native AassetManager文件层次结构
- 使用Android NDK建立Mariadb客户端
- 推荐哪个操作系统平台使用Android NDK进行本地游戏开发
- 在 Windows 上使用 Android ADT 构建 NDK 应用程序
- Eclipse索引器没有使用Android NDK找到功能
- 使用Java和C 一起使用Android项目