[英]OpenCL floor function doesn't return correct number
I am trying to convert a CUDA code snippet in OpenCL.我正在尝试在 OpenCL 中转换 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;
# 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
. double
是77.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.