如何检测int
C中的符号?
这个问题主要是关于历史机器的。我要问的是如何区分整数是0还是-0。在 1 的补码和符号/幅度 int 编码中,0(或 +0)和 -0 都是可能的。
简单的符号位测试是与0
.
int x;
printf("sign bit is %s\n", (x < 0) ? "set" : "not set");
x
但是当is时,这在 1 的补码和符号幅度上失败了-0
。
第一种候选方法:模板测试。
由于 C 定义int
无论整数编码如何,都必须具有符号位,因此以下内容应该有效。
int x;
int SignBitMask = tbd;
printf("sign bit is %s\n", (x & SignBitMask) ? "set" : "not set");
问题变成了如何确定SignBitMask
C 中的值?
SignBitMask = INT_MAX + 1
似乎是一个起点。
第二种候选方法:创建函数并检查位模式:
int IsSignBitSet(int x) {
if (x > 0) return 0;
if (x < 0) return 1;
int zp = 0;
if (memcmp(&x, &zp, sizeof x) == 0) return 0;
int zn = -0; // Is this even the way to form a -0?
if (memcmp(&x, &zn, sizeof x) == 0) return 1;
// If we get here, now what?
return ?;
}
我在想没有可移植的统一解决方案——也许是因为不再需要。
原因:我想知道如何检测和打印各种带符号的零。
注意:我在这里故意避免使用“C”标签,并认为我会先尝试“历史”标签。
[编辑]答案
结合 3 个答案的信息和 C11dr 6.2.6.2“整数类型”(对于,必须int
存在单个符号位,正符号位为 0,负符号位为 1),解决方案(出现独立于 1 的补码,2补码和符号/幅度整数编码)是
int IsSignBitSet_Best(int x) {
// return 1 if x is less than 0 _or_ x is arithmetically 0 with some bit set.
return (x < 0) || ((x == 0) && (* ((unsigned int*) &x) ));
}
直接掩码方法最简单,但还没有提出高度便携的掩码定义
int IsSignBitSet_Simple(int x) {
static unsigned SignBitMask = 0x80; // Or some other platform dependent mask
return ((unsigned)x & SignBitMask) != 0;
}