2010-06-15 98 views
3

我在NVIDIA的CUDA SDK示例中找到了此代碼。浮點精度細微差別

void computeGold(float* reference, float* idata, const unsigned int len) 
{ 
    reference[0] = 0; 
    double total_sum = 0; 
    unsigned int i; 
    for(i = 1; i < len; ++i) 
    { 
     total_sum += idata[i-1]; 
     reference[i] = idata[i-1] + reference[i-1]; 
    } 
    // Here it should be okay to use != because we have integer values 
    // in a range where float can be exactly represented 
    if (total_sum != reference[i-1]) 
     printf("Warning: exceeding single-precision accuracy. Scan will be inaccurate.\n"); 
} 
//(C) Nvidia Corp 

有人可以告訴我一個警告將被打印的情況,最重要的是,爲什麼。

回答

2

這個函數是用一定範圍的輸入數據來編寫的。如果未達到輸入數據期望值,則將顯示以下警告:

#include <stdio.h> 
#define COUNT_OF(x) (sizeof(x)/sizeof(0[(x)])) 

void computeGold(float* reference, float* idata, const unsigned int len) 
{ 
    double total_sum = 0; 
    unsigned int i; 

    reference[0] = 0; 

    for(i = 1; i < len; ++i) 
    { 
     total_sum += idata[i-1]; 
     reference[i] = idata[i-1] + reference[i-1]; 
    } 
    // Here it should be okay to use != because we have integer values 
    // in a range where float can be exactly represented 
    if (total_sum != reference[i-1]) 
     printf("Warning: exceeding single-precision accuracy. Scan will be inaccurate.\n"); 
} 
//(C) Nvidia Corp 


float data[] = { 
    1.0, 
    2.0, 
    3.0, 
    4.0, 
    5.0 
}; 

float data2[] = { 
    123456.0, 
    999999.0, 
    999999.0, 
    999999.0, 
    999999.0, 
    999999.0, 
    999999.0, 
    999999.0, 
    999999.0, 
    999999.0, 
    999999.0, 
    999999.0, 
    999999.0, 
    999999.0, 
    999999.0, 
    999999.0, 
    999999.0, 
    999999.0, 
    123456.0 
}; 

float ref[COUNT_OF(data2)] = {0.0}; 

int main() 
{ 
    computeGold(ref, data, COUNT_OF(data)); 
    computeGold(ref, data2, COUNT_OF(data2)); 
    return 0; 
} 
+0

但我的問題是,計算黃金內部的計算都以完全相同的順序添加完全相同的數字,哪裏出錯? – 0fnt 2010-06-16 12:52:50

+0

@ user247077:你是說你看到警告,但不是所有的時間 - 即使是同一組數字? – 2010-06-16 14:13:05

+0

不,我要說的是,如果這組數字是x1,x2,...,xn,那麼在這兩種情況下,實際添加和參考添加,我將它們以相同的順序相加。那爲什麼我得到一個錯誤。如果你能回答這個問題,我會很感激。謝謝。 PS我很抱歉回覆晚了。我認爲,stackoverflow會通知我的評論。 – 0fnt 2010-06-21 05:56:19

5

通常情況下,你不能求和許多浮點數。

最終總和變成與每個新增數字不同的數量級,因此精度會丟失。例如,在浮動的情況下,添加一百萬個相同數量級的數字會得出與一千萬相同的結果,因爲在完成時,添加的每個新數字都不會改變任何內容。

這裏有一些算法,每個增加的數字都涉及到幾次乘法(事實上,只是爲了正確地求和數字)。是的,浮點是棘手的。

參見http://floating-point-gui.de/

+0

+1表示鏈接。我將鏈接到*每個CS應該知道的內容...... *,但是那裏有聯繫,並且閱讀困難得多。 – RBerteig 2010-06-15 19:21:17

+0

其實我不喜歡這個gui.de,但我只是看不到在網上找到一個更好的。 – 2010-06-15 19:39:29

1

float通常具有的範圍內類似+/- 1e38,但只有約5或6位數字位精度。這意味着,例如,可以存儲類似12345678的東西,但只能存儲約6位精度的數字,所以您會收到警告。