如何在C语言中获得int的二进制补码?
例如,如果我有一个整数,比如-254,我该如何将其转换为100000010?
是否有办法从整数变量中提取二进制补码值,因为在C中,ints存储在二进制补码中?
如何在C语言中获得int的二进制补码?
例如,如果我有一个整数,比如-254,我该如何将其转换为100000010?
是否有办法从整数变量中提取二进制补码值,因为在C中,ints存储在二进制补码中?
unsigned int
,那么你可以反转位~
并加上1
来得到2的补码值。x=(~y)+1;
如果你的机器使用2的补码表示signed int
,那么根据实现的定义,这应该转换为正确的signed int
值。unsigned
类型。~(unsigned)y)+1
的身份标识,而不是直接使用0U - y
或一元运算符-(unsigned)y
?二进制补码使用与无符号加/减(和非扩展乘法)相同的二进制操作,并且C已经有一个取反运算符。 - Peter Cordes-
和二进制减法是一样的,所以我们可以用无符号减法在 C 中实现它。你的版本依赖于无符号二进制加法,而我的版本则依赖于无符号二进制减法。不需要单独的加、减、取反指令(只需要除法和扩展乘法)是计算机使用二进制补码表示有符号数的原因之一。 - Peter Cordes1 + ~(unsigned)y
相当于使用二进制补码恒等式是有意义的,但从其他SO问题来看,很多初学者会陷入其中,并没有意识到它与从0中减去相同。例如,我看到[汇编]问题,人们实际上使用了 not
/ inc
指令,而不是 neg
(在x86上是二进制补码机器),因为他们没有意识到二进制补码求反是二进制求反。至少在C语言中,您可以让编译器在针对二进制补码机器进行编译时将其转换回有符号的 -
。 - Peter Cordes知道在C语言中,整数使用二进制补码存储。
虽然不能保证所有计算机都是如此,但在实践中几乎所有计算机都使用二进制补码。
有没有办法从整数变量中提取出二进制补码值?
它已经是用二进制补码格式存储的,所以不清楚你在问什么。似乎你是想知道如何以二进制格式打印变量?
int data = -254;
const size_t BITS = 8*sizeof(data);
char bin_str[BITS+1];
for(unsigned int i=0; i<BITS; i++)
{
unsigned int mask = 1u << (BITS - 1 - i);
bin_str[i] = (data & mask) ? '1' : '0';
}
bin_str[BITS] = '\0';
如果一个数是负数,你可以通过从0x80000000中减去该数来将其转换为二进制补码。这适用于使用二进制补码表示负值的32位整数机器,但如果该值为正,则会导致二进制补码取反。对于二进制补码负数的右移将会在左侧填充1,我们可以利用这一点来创建一个掩码,以选择原始值或将有符号幅值负值转换为二进制补码负值。
int sm2tc(int x) {
int m = x >> 31;
return (~m & x) | (((x & 0x80000000) - x) & m);
}
原始代码由Apriori发布
0x80000000
是一个无符号字面量,所以这段代码有错误。首先,不要在有符号类型上使用位运算符。 - Lundin实际上,有一种简单的方法可以做到这一点。只需将您的数字转换为二进制字符串,然后将该字符串转换回整数即可。
使用 itoa
,它可以将一个数字以字符串形式转换为给定的基数。
http://www.cplusplus.com/reference/cstdlib/itoa/
然后,只需使用熟悉的atoi将其转换回int。
itoa
不是标准函数,也不适用于 gcc
。 - riteshtch