2

このようにすることにしました

  • フリップ番号 0=1、1=0
  • LSBに1を加算
  • キャリーの場合、array[i]==0 までループ

しかし、私は最後の点で立ち往生しています。条件付きループでそれをどのように言うことができますか?

4

5 に答える 5

2

あなたは拡張算術について話している。ほとんどのプロセッサは、すべての加算演算のキャリーアウトとオーバーフローの結果を持っていますが、C はそれらへのアクセスを提供していません。

あなたの問題は、数字が大きくなるにつれて数字が長くなることです。あなたが持っている最後のビットにいて、実行する必要がある場合は、別のビットが必要です! つまり、ビットの配列を再割り当てする必要があります (配列を使用している場合)。

もちろん、より実用的な解決策は、個々のビットではなくネイティブの整数を使用することです。これは、プロセッサが既に 2 の補数を適切に処理しているためです。次に、元の数が に等しい場合、1 を追加するとキャリーアウトになることがわかります(unsigned) -1。根本的な問題は残っています。最後のものを実行する必要がある場合は、unsigned別のものを割り当てる必要があります。

于 2010-04-05T22:42:09.557 に答える
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 に答える
0

次のように、2 の補数をもっと簡単に行うことができます。

  • 1 が見つかるまで変更しません。
  • 最初の 1 を取得した直後に、次の 0 を 1 に、1 を 0 に反転し、これを続けます。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

したがって、数値をビットを表す int の配列として格納します。添付したコード例では、 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 の場合はゼロにリセットし、ビットに沿って続行します。ビットが 0 の場合は、1 に設定し、ループから抜け出します。(運ぶものがないので、追加は完了です。)

それが役立つことを願っています。ところで、上記のコードでは、ビットが「後方」に格納されていることに注意してください。LSB はインデックス 0 にあります。

于 2010-04-05T22:14:21.207 に答える