我决定这样做
- 翻转数字 0=1, 1=0
- LSB 加 1
- 如果进位,则循环直到 array[i]==0
但我坚持最后一点;我怎么能在条件循环中这么说?
你在谈论扩展算术。大多数处理器都有每次加法运算的进位和溢出结果,但 C 不提供对它们的访问。
您的问题是数字越大,数字就越长。如果您处于最后一点,并且需要执行,那么您还需要一点!这意味着您需要重新分配位数组(如果您使用的是数组)。
当然,更实用的解决方案是使用本机整数而不是单个位,因为您的处理器已经很好地处理了二进制补码。然后,您知道如果原始数字等于 ,则加一会导致进位(unsigned) -1
。根本问题仍然存在;如果您需要执行最后一个,则unsigned
需要分配另一个。
您可以像下面这样更简单的方式进行 2 的补码:
你可以自己检查算法的有效性。并且实现应该如下所示:
// an 8-bit number
int number[8] = {0, 1, 1, 1, 0, 1, 0, 0};
int i;
bool gotFirstOne = false;
// flip bits after you first encountered an 1
for (i = 0; i < 8; i++)
{
if(gotFirstOne == false){
if(number[i] == 1) {
gotFirstOne = true;
}
}
else {
number[i] = !number[i];
}
}
if(number[7] == 0) {
printf("Overflow occurred");
}
干杯!!!!
因此,您将数字存储为整数数组,它们代表位。在您附加的代码示例中,您忘记增加i变量,并检查它是否超过了数组的大小。
你可以写这样的东西(我假设数组的大小是5):
for (i = 0; i < 5; i++)
{
if (array1[i] == 1)
array1[i] = 0;
else // we found a 0
array1[i] = 1;
break;
}
我不太确定你在做什么,但也许这会有所帮助:
#define countof(x) (sizeof(x) / sizeof(x[0]))
// an 8-bit number
int byte[8] = {0, 1, 1, 0, 1, 1, 1, 0}; // 1 = on, 0 = off
// flip all bits
for (size_t i = 0; i < countof(byte); ++i)
{
byte[i] = !byte[i];
}
// add one
for (size_t i = 0; i < countof(byte); ++i)
{
if (byte[i]) // if on
{
byte[i] = 0; // "add 1, reset to zero", and carry (no break)
}
else // if off
{
byte[i] = 1; // turn on
break; // nothing to carry, stop adding
}
}
(我不知道如何在不解释代码的情况下将您推向正确的方向,对不起。我认为您已经足够接近了,这仍然很有帮助。)
您会看到,当您添加一个时,如果该位已经为 1,请将其重置为零,然后继续沿这些位。如果该位为零,则将其设置为 1,然后跳出循环。(没什么可携带的,所以我们完成了添加。)
希望有帮助。顺便说一句,您会注意到这些位在上面的代码中“向后”存储。LSB 在索引 0 处。
我对 2 的补码的回答,记住这是 12 位补码,您可以根据需要更改掩码或整数类型。这工作得很好,也可以使用宏来完成。
int twos_compliment(unsigned short a)
{
int result;
result = 0x0FFF&a;
result = (((result&0x800)?(0<<11):(1<<11))|((result&0x400)?(0<<10):(1<<10))
|((result&0x200)?(0<<9):(1<<9))|((result&0x100)?(0<<8):(1<<8))
|((result&0x080)?(0<<7):(1<<7))|((result&0x040)?(0<<6):(1<<6))
|((result&0x020)?(0<<5):(1<<5))|((result&0x010)?(0<<4):(1<<4))
|((result&0x008)?(0<<3):(1<<3))|((result&0x004)?(0<<2):(1<<2))
|((result&0x002)?(0<<1):(1<<1))|((result&0x001)?0:1));
return result=result+1;
}