C 无符号整数4的一元求反

C 无符号整数4的一元求反,c,C,如果x是无符号整数类型,则这些语句中是否存在差异: return (x & 7); 及 据我所知,对无符号值求反得到的值为max\u int-value。但是,在任何特定边界条件下,上述两个语句的返回值(即真/假)是否存在差异,或者它们在功能上是否相同?测试代码: #include <stdio.h> static unsigned neg7(unsigned x) { return -x & 7; } static unsigned pos7(unsigned

如果x是无符号整数类型,则这些语句中是否存在差异:

return (x & 7);

据我所知,对无符号值求反得到的值为
max\u int-value
。但是,在任何特定边界条件下,上述两个语句的返回值(即真/假)是否存在差异,或者它们在功能上是否相同?

测试代码:

#include <stdio.h>

static unsigned neg7(unsigned x) { return -x & 7; }

static unsigned pos7(unsigned x) { return +x & 7; }

int main(void)
{
    for (unsigned i = 0; i < 8; i++)
        printf("%u: pos %u; neg %u\n", i, pos7(i), neg7(i));
    return 0;
}
对于4(以及0)的特定情况,没有差异;对于其他值,则存在差异。您可以扩展输入范围,但输出将产生相同的模式。

测试代码:

#include <stdio.h>

static unsigned neg7(unsigned x) { return -x & 7; }

static unsigned pos7(unsigned x) { return +x & 7; }

int main(void)
{
    for (unsigned i = 0; i < 8; i++)
        printf("%u: pos %u; neg %u\n", i, pos7(i), neg7(i));
    return 0;
}

对于4(以及0)的特定情况,没有差异;对于其他值,则存在差异。您可以扩展输入范围,但输出将产生相同的模式。

首先,对
无符号int
值求反将产生
UINT\u MAX-原始值+1
。(例如,
0
在否定项下保持
0
)。描述否定的另一种方法是所有位的完全反转,然后是增量


我们甚至不清楚为什么要问这个问题,因为很明显,我们想到的第一个例子-
unsigned int
value
1
,已经在表达式中产生了不同的结果
1u&7
1
,而
-1u&7
7
。你是说别的吗?

首先,对
无符号int
值求反会产生
UINT\u MAX-原始值+1
。(例如,
0
在否定项下保持
0
)。描述否定的另一种方法是所有位的完全反转,然后是增量


我们甚至不清楚为什么要问这个问题,因为很明显,我们想到的第一个例子-
unsigned int
value
1
,已经在表达式中产生了不同的结果
1u&7
1
,而
-1u&7
7
。你是说别的吗?

如果你特别要求真/假(即是零/不是零)和2的补码,那么实际上没有区别。(但是,您不仅返回一个简单的真值,而且允许
true
使用不同的位模式。只要调用方不区分,就可以了。)

考虑2的补码否定是如何形成的:将位反转,然后递增。由于您只获取最低有效位,因此增量将没有进位。这是必须的,所以除了一系列最低有效位之外,你不能做任何事情

让我们看看这两种情况:

首先,如果三个低位为零(对于
false
等效值)。反转得到所有的一,递增将使它们再次为零。第四位和更高有效位可能不同,但它们不会影响最低有效位,也不会影响结果,因为它们被屏蔽了。所以这个就留下来了

第二,如果三个低位不是全部为零(对于
true
等效值)。唯一可以变为
false
的方法是当增量操作将它们保留为零时,这只能发生在它们之前都为1的情况下,而反过来,这也只能发生在它们在反转之前都为零的情况下。那不可能,因为这是第一例。同样,较高的有效位不影响三个低位,它们被屏蔽。因此,结果不会改变


但同样,只有当调用者只考虑真值(所有位为零/不是所有位为零)并且掩码允许从最低有效位开始的一系列位没有间隙时,这才有效。

如果您特别要求真/假(即为零/非零)和二的补码,那么实际上没有区别。(但是,您不仅返回一个简单的真值,而且允许
true
使用不同的位模式。只要调用方不区分,就可以了。)

考虑2的补码否定是如何形成的:将位反转,然后递增。由于您只获取最低有效位,因此增量将没有进位。这是必须的,所以除了一系列最低有效位之外,你不能做任何事情

让我们看看这两种情况:

首先,如果三个低位为零(对于
false
等效值)。反转得到所有的一,递增将使它们再次为零。第四位和更高有效位可能不同,但它们不会影响最低有效位,也不会影响结果,因为它们被屏蔽了。所以这个就留下来了

第二,如果三个低位不是全部为零(对于
true
等效值)。唯一可以变为
false
的方法是当增量操作将它们保留为零时,这只能发生在它们之前都为1的情况下,而反过来,这也只能发生在它们在反转之前都为零的情况下。那不可能,因为这是第一例。同样,较高的有效位不影响三个低位,它们被屏蔽。因此,结果不会改变


但同样,只有当调用者只考虑真值(所有位为零/不是所有位为零)并且掩码允许从最低有效位开始的一系列位没有间隙时,这才有效。

您可以很容易地自己测试,不是吗?总的来说,是的,这是有区别的。你可以很容易地自己测试,不是吗?一般来说,是的,这是有区别的。这也表明,与OP所认为的相反,
&
运算符不会返回布尔真/假。只是好奇。。。为什么要将这些函数标记为static?@RastaJedi:因为它们没有在这个文件之外使用,也没有声明它们的头,我使用的编译选项(
gcc-O3-g-std=c11-Wall-Wextra-Wmissing)-
0: pos 0; neg 0
1: pos 1; neg 7
2: pos 2; neg 6
3: pos 3; neg 5
4: pos 4; neg 4
5: pos 5; neg 3
6: pos 6; neg 2
7: pos 7; neg 1