C代码解释

C代码解释,c,C,以下函数用于比较两个浮点值,但在某些特定情况下比常规比较快(例如在Cortex-A8上) 有人能解释一下它到底是如何工作的吗?这段代码利用了IEEE 754格式的浮点数结构。该结构本身是专门为此类操作设计的,以便快速进行比较操作 每个单精度IEEE 754编号有三个部分(从MSB到LSB的顺序): 符号位 指数部分(8位) 尾数的有效位(23位) f1大于f2如果: f1为正,f2为负 f1和f2均为正值,但f1的指数大于f2 f1和f2均为正值,指数相同,但f1的有效位大于f2 前两个i

以下函数用于比较两个浮点值,但在某些特定情况下比常规比较快(例如在Cortex-A8上)


有人能解释一下它到底是如何工作的吗?

这段代码利用了IEEE 754格式的浮点数结构。该结构本身是专门为此类操作设计的,以便快速进行比较操作

每个单精度IEEE 754编号有三个部分(从MSB到LSB的顺序):

  • 符号位
  • 指数部分(8位)
  • 尾数的有效位(23位)
f1
大于
f2
如果:

  • f1
    为正,
    f2
    为负
  • f1
    f2
    均为正值,但
    f1
    的指数大于
    f2
  • f1
    f2
    均为正值,指数相同,但
    f1
    的有效位大于
    f2
  • 前两个if
    f1
    f2
    的相反值为负值
如果两个浮点数都在表示形式中,则可以将它们作为整数进行比较。不幸的是,IEEE 754没有使用2的补码来表示负数,这就是为什么这段代码执行转换,以便能够将数字作为有符号整数进行比较

下面是关于每一行代码作用的逐步说明:

i1 = *(int*)f1; // reading float as integer
i2 = *(int*)f2; // reading float as integer
这个函数使用了一个事实,即在大多数32位系统上,
sizeof(int)==sizeof(float)
将浮点数读入规则的有符号整数变量

t1 = i1 >> 31;
这个函数提取
f1
的符号位。如果
f1
为负值,其MSB将为
1
,因此
i1
将为负值。将其向右移动31位将保留符号,因此如果
i1
为负
t1
将所有位设置为
1
(等于-1)。如果
f1
为正,其符号位将为
0
,最后
t1
将等于
0

i1 = (i1 ^ t1) + (t1 & 0x80000001);
如果符号位为
1
,如果
f1
为负数,该行将执行到2的补码表示的转换

t2 = i2 >> 31;
i2 = (i2 ^ t2) + (t2 & 0x80000001);
下面是它的工作原理:如果
f1
为正,那么
t1
0
(i1^t1)
将为
i1
(t1&0x8000001)
将为
0
,最后
i1
将保留其原始值。如果
f1
为负,则
t1
将所有位设置为
1
,RHS上的第一个表达式将是
i1
的位反转,第二个表达式将等于
0x8000001
。这样,
i1
将转换为其位反转,并添加
1
。但这将导致一个正数,因为MSB将被清除,这就是为什么还要添加
0x8000000
以保持该数字为负数

t2 = i2 >> 31;
i2 = (i2 ^ t2) + (t2 & 0x80000001);
对f2执行与上述相同的操作

return i1 > i2;

只需比较得到的两个有符号整数。大多数CPU都有专用的指令来在硬件中执行有符号比较。

此代码利用IEEE 754格式的浮点数字结构。该结构本身是专门为此类操作设计的,以便快速进行比较操作

每个单精度IEEE 754编号有三个部分(从MSB到LSB的顺序):

  • 符号位
  • 指数部分(8位)
  • 尾数的有效位(23位)
f1
大于
f2
如果:

  • f1
    为正,
    f2
    为负
  • f1
    f2
    均为正值,但
    f1
    的指数大于
    f2
  • f1
    f2
    均为正值,指数相同,但
    f1
    的有效位大于
    f2
  • 前两个if
    f1
    f2
    的相反值为负值
如果两个浮点数都在表示形式中,则可以将它们作为整数进行比较。不幸的是,IEEE 754没有使用2的补码来表示负数,这就是为什么这段代码执行转换,以便能够将数字作为有符号整数进行比较

下面是关于每一行代码作用的逐步说明:

i1 = *(int*)f1; // reading float as integer
i2 = *(int*)f2; // reading float as integer
这个函数使用了一个事实,即在大多数32位系统上,
sizeof(int)==sizeof(float)
将浮点数读入规则的有符号整数变量

t1 = i1 >> 31;
这个函数提取
f1
的符号位。如果
f1
为负值,其MSB将为
1
,因此
i1
将为负值。将其向右移动31位将保留符号,因此如果
i1
为负
t1
将所有位设置为
1
(等于-1)。如果
f1
为正,其符号位将为
0
,最后
t1
将等于
0

i1 = (i1 ^ t1) + (t1 & 0x80000001);
如果符号位为
1
,如果
f1
为负数,该行将执行到2的补码表示的转换

t2 = i2 >> 31;
i2 = (i2 ^ t2) + (t2 & 0x80000001);
下面是它的工作原理:如果
f1
为正,那么
t1
0
(i1^t1)
将为
i1
(t1&0x8000001)
将为
0
,最后
i1
将保留其原始值。如果
f1
为负,则
t1
将所有位设置为
1
,RHS上的第一个表达式将是
i1
的位反转,第二个表达式将等于
0x8000001
。这样,
i1
将转换为其位反转,并添加
1
。但这会让你很沮丧