简体   繁体   English

OpenCL floor function 没有返回正确的数字

[英]OpenCL floor function doesn't return correct number

I am trying to convert a CUDA code snippet in OpenCL.我正在尝试在 OpenCL 中转换 CUDA 代码片段。

CUDA code: CUDA 代码:
# Variable point is CUDA float4.
# X_MIN_RANGE, Y_MIN_RANGE, PILLAR_SIZE and GRID_X_SIZE are all defined as
# constants in a header file.

int idx = floorf((point.x - X_MIN_RANGE)/PILLAR_SIZE);
int idy = floorf((point.y - Y_MIN_RANGE)/PILLAR_SIZE);
unsigned int index = idy * GRID_X_SIZE + idx;
OpenCL code: OpenCL 代码:
# Variable point_coord is OpenCL float4.
# X_MIN_RANGE, Y_MIN_RANGE, PILLAR_SIZE and GRID_X_SIZE are defined as constants using #define.

#define X_MIN_RANGE 0.0
#define Y_MIN_RANGE -39.68
#define PILLAR_SIZE 0.16
#define GRID_X_SIZE 432

/*... Some code here...*/

int idx = floor((point.x - X_MIN_RANGE) / PILLAR_SIZE);
int idy = floor((point.y - Y_MIN_RANGE) / PILLAR_SIZE);
unsigned int index = idy * GRID_X_SIZE + idx;

I have some issues with the results of floor.我对 floor 的结果有一些疑问。 For instance, for a point of coordinates {12.48, -10.629, -0.223, 0.4}, X_MIN_RANGE = 0.0, Y_MIN_RANGE = -39.68, PILLAR_SIZE = 0.16 and GRID_X_SIZE = 432 I'm expecting to see:例如,对于坐标点 {12.48,-10.629,-0.223,0.4},X_MIN_RANGE = 0.0,Y_MIN_RANGE = -39.68,PILLAR_SIZE = 0.16 和 GRID_X_SIZE = 432 我期待看到:

idx = floor((12.48 - 0.0) / 0.16) = floor(78.0) = 78 idx = 地板 ((12.48 - 0.0) / 0.16) = 地板 (78.0) = 78
idy = floor((-10.69 + 39.68) / 0.16) = floor(181.1875) = 181 idy = floor((-10.69 + 39.68) / 0.16) = floor(181.1875) = 181

index = 181 * 432 + 78 = 78270索引 = 181 * 432 + 78 = 78270

For the CUDA code, I am getting the correct result, however for the OpenCL code I am getting 78269 for the same coordinates as the floor operation for idx returns 77 instead of 77. I had a look for similar examples and it always happens when the decimal part of the argument in floor is 0, so I assume that the result falls on the wrong side of the integer.对于 CUDA 代码,我得到了正确的结果,但是对于 OpenCL 代码,我得到 78269 相同的坐标,因为 idx 的 floor 操作返回 77 而不是 77。我查看了类似的例子,它总是发生在floor 中参数的小数部分为 0,因此我假设结果落在 integer 的错误一侧。

As this part of the code needs to be quite accurate, do you know how can I make sure floor rounds integers correctly?由于这部分代码需要非常准确,您知道如何确保 floor 正确舍入整数吗? I have alredy tried to rearrange the operations and to use double instead of float, but that didn't help.我已经尝试重新安排操作并使用 double 而不是 float,但这没有帮助。

(point.x - X_MIN_RANGE)/PILLAR_SIZE is calculated as double , because all defines are double . (point.x - X_MIN_RANGE)/PILLAR_SIZE计算为double ,因为所有定义都是double So the result is a double .所以结果是double

If you then use floorf (the f at the end stands for float ), it will be casted to a float before the function call.如果您随后使用floorf (末尾的 f 代表float ),它将在 function 调用之前转换为float If you use floor , it stays a double .如果你使用floor ,它会保持double

The float value is indeed 78.00000 exact, so floorf returns 78 . float值确实准确为78.00000 ,因此floorf返回78

The double is 77.99999713897705078125 and then floor returns 77 . double77.99999713897705078125然后floor返回77

You can fix that by either using float for the calculation or cast the result before the function call.您可以通过使用float进行计算或在 function 调用之前转换结果来解决此问题。 You could also add a very small number, like 0.0001 before the floor to remove floating point inexactness.您还可以添加一个非常小的数字,例如在floor之前添加0.0001以消除浮点数的不精确性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM