我在GPU上执行以下操作
float decPart = valAtIndex - (int)valAtIndex;
int docID = decPart * numDocs;
其中valAtIdex类型为float
,numDocs类型为float
。对于我的情况,decPart为0.2,numDocs为10.但是,当我打印docID时,它打印为1(应该是2)。有人可以告诉我,我在哪里弄错了吗?
以下是完整的方法,如果有帮助
__global__
void finalNc(float* scSortedCounts, int* pos, int* maxCountEx, float numDocs,
int lengthStreamCompacted, int* finalNc, int actualLengthPos,
float* val, int* docIndex, int* acV ,int* ptwrite,int* diff,
int* posIndex)
{
int index = blockDim.x * blockIdx.x + threadIdx.x;
if(index < lengthStreamCompacted){
float valAtIndex = scSortedCounts[index];
float decPart = valAtIndex - (int)valAtIndex;
int docID = decPart * numDocs;
int actualCount = (int)valAtIndex;
int placeToWrite = maxCountEx[docID] + actualCount;
if( index == (lengthStreamCompacted -1 )){
finalNc[placeToWrite] = actualLengthPos - pos[index];
}else{
finalNc[placeToWrite] = pos[index + 1] + pos[index];
}
}
}
答案 0 :(得分:3)
对于您提到的情况,您看到的结果似乎是正确的,并且您的混淆的根源是计算中间结果的IEEE单精度表示(并且可能在打印或显示时舍入那些中间结果)。
对于您提供的示例,值0.2f不能完全表示为binary32值。两个可能的值是
3E4CCCCC (1.99999988079071044921875E-1)
或
3E4CCCCD (2.0000000298023223876953125E-1)
如果第一个值是docID
的实际值,那么您提到的中间计算应该生成1(这是您观察到的)。如果是第二个值,则结果为2.这是绝对预期的行为。
为了说明IEEE舍入模式的效果并帮助您放心,这里没有错误,请查看以下示例代码,该代码执行您要求的三个可能{{1}之一的计算{}}转换为float
转换 - 纯粹截断,IEEE 754向负无穷大舍入,IEEE 754向无穷大舍入。我已经模拟了内核,并在1到10之间的一组随机浮点值上为每个案例运行它。您可以自己编译并运行它并验证纯截断(如在代码中)确实按预期工作,如以及符合IEEE标准的“向上舍入”和“向下舍入”转换的行为。
integer