gpt4 book ai didi

c++ - 将 float 宏与 int* 一起切换 - 它有什么作用?

转载 作者:行者123 更新时间:2023-11-28 02:03:46 25 4
gpt4 key购买 nike

我试图理解 OpenCV 中的 AKAZE 功能实现,当我遇到以下宏时感到困惑:

/* IEEE754 constants and macros */
#define CV_TOGGLE_FLT(x) ((x)^((int)(x) < 0 ? 0x7fffffff : 0))

它以下列方式用于 MLDB 二进制比较(我删除了所有不相关的代码部分):

void MLDB_Binary_Comparisons(float* values)
{
int* ivalues = (int*)values;
for (int i = 0; i < count * chan; i++)
ivalues[i] = CV_TOGGLE_FLT(ivalues[i]);

/* ... The ivalues are then compared to each other using the > operator */
}

有人知道这里发生了什么吗?将 float* 转换为 int* 真的安全吗?这个宏究竟做了什么?

提前致谢!

最佳答案

本质上,它以不可移植的方式对 float 据进行一些二进制操作:对于 int 的相对大小有明显的假设。和 float以及他们的代表。我认为如果 int是一个 32 位 2 的补码整数,float是一个 IEEE 32 位浮点值,那么它允许您仅使用整数运算来比较浮点值。

更详细...

int* ivalues = (int*)values;

这只是为我们提供了一个用于遍历浮点值的指针。它们被解释ints ,未转换int - 换句话说,没有理由认为 float值为 1.0将映射到 int 1 的值.因此,您可以做的主要事情是按位运算,或依赖于理解用于 float 的二进制格式的特定操作。 .

看宏观...

#define  CV_TOGGLE_FLT(x) ((x)^((int)(x) < 0 ? 0x7fffffff : 0))

x (请记住,只是一些代表浮点值的位,但这里我们只是将其视为位模式)与 0 中的任何一个进行异或运算。 (无效)或 0x7fffffff (反转低位 31 位)。做什么的决定是基于是否x是否小于零。

我认为这个宏是基于一个假设 int是 32 位 2 的补码表示。这意味着 x < 0如果设置了最高位,则为真。与 0x7fffffff 的异或将反转其他位。这意味着 -1 ,最正负数,从 0xffffffff 变为至 0x8000000 ,这是最负的负数(-2147483648),同样是0x8000000变成 0xffffffff .当您使用 >在此之后比较两个负数,这意味着更负的数现在是更正的数,并且将采用“大于”分支。比较两个正数是不变的,并且将正数与负数进行比较,如您所料,正数仍然总是更大。

这让您可以对 float 进行比较仅使用整数运算。这是因为方式 float s,在 IEEE 格式中,存储负数与 2 的补码有很大不同:符号位实际上只是一个标志,表示值是正数还是负数,其余位存储数字的大小。一旦您应用了 CV_TOGGLE_FLT(x)您没有可以直接使用的值,但它们的排序方式与原始 float 相同值(value)观。

关于c++ - 将 float 宏与 int* 一起切换 - 它有什么作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38372487/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com