2

我决定这样做

  • 翻转数字 0=1, 1=0
  • LSB 加 1
  • 如果进位,则循环直到 array[i]==0

但我坚持最后一点;我怎么能在条件循环中这么说?

4

5 回答 5

2

你在谈论扩展算术。大多数处理器都有每次加法运算的进位和溢出结果,但 C 不提供对它们的访问。

您的问题是数字越大,数字就越长。如果您处于最后一点,并且需要执行,那么您还需要一点!这意味着您需要重新分配位数组(如果您使用的是数组)。

当然,更实用的解决方案是使用本机整数而不是单个位,因为您的处理器已经很好地处理了二进制补码。然后,您知道如果原始数字等于 ,则加一会导致进位(unsigned) -1。根本问题仍然存在;如果您需要执行最后一个,则unsigned需要分配另一个。

于 2010-04-05T22:42:09.557 回答
0

您可以像下面这样更简单的方式进行 2 的补码:

  • 保持不变,直到找到 1。
  • 在获得第一个 1 之后,将接下来的 0 翻转为 1,将 1 翻转为零并继续执行此操作。如果 MSB 变为 0,则表示发生了溢出。

你可以自己检查算法的有效性。并且实现应该如下所示:

// 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");
}

干杯!!!!

于 2012-11-21T17:00:46.167 回答
0

因此,您将数字存储为整数数组,它们代表位。在您附加的代码示例中,您忘记增加i变量,并检查它是否超过了数组的大小。

你可以写这样的东西(我假设数组的大小是5):

for (i = 0; i < 5; i++)
{
    if (array1[i] == 1)
        array1[i] = 0;
    else // we found a 0
        array1[i] = 1;
        break;
}
于 2010-04-05T22:13:23.090 回答
0

我不太确定你在做什么,但也许这会有所帮助:

#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 处。

于 2010-04-05T22:14:21.207 回答
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;
}
于 2013-02-04T11:40:24.497 回答