2010-06-15 81 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位精度的数字,所以您会收到警告。