簡體   English   中英

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]

這是你的問題。 除了要比較一個double和一個int並且不知道哪個類型將被轉換為另一個類型的事實之外,您還要將浮點數與==運算符進行比較。

比較浮點數和雙精度數不會像這樣工作,因為

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來源。 但是,這不是最好的方法,因為它破壞了庫的模塊化。 我必須解決此問題,但這將是一個非常不同的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM