0

したがって、これは可能であり、ビットごとの操作とマスクは非常に役立つと言われていますが、それらがどのように機能するかについて何かが欠けているに違いありません。

数値、たとえば x が y の倍数かどうかを計算しようとしています。x が y の倍数である場合、それ以外の場合は、x を増やして、x よりも大きい y の最も近い倍数に到達させたいと考えています (すべての x が結果に収まるように)。C の学習を始めたばかりで、これらのタスクのいくつかを理解するのに苦労しています。

これが私が試したものですが、5、9、または24などの数字を入力すると、それぞれ0、4、4が得られます。

    if(x&(y-1)){ //if not 0 then multiple of y
        x = x&~(y-1) + y;
    }

説明、舞台裏で行われている数学の例は大歓迎です。

編集:明確にするために、アイテムが倍数であるかどうかを取得するためのビットのシフトをある程度理解しています。(返信で説明したように、10100 は 101 の倍数であり、シフトされたばかりです)。16 が 10000 の場合、その補数は 01111 です。この補数を使用して、項目が 16 の倍数かどうかを確認するにはどうすればよいでしょうか? また、誰かが上記のコードの数値的な説明を与えることができますか? これを表示すると、なぜ機能しないのかを理解するのに役立つかもしれません。うまくいかない理由がわかれば、自分で問題を解決できると思います。

4

3 に答える 3

1

これにビット単位の操作を使用することを考えるのはなぜですか? 彼らは確かに彼らの場所を持っていますが、これはそうではありません.

より良い方法は、単に次のようなものを使用することです:

unsigned multGreaterOrEqual(unsigned x, unsigned y) {
    if ((x % y) == 0)
        return x;
    return (x / y + 1) * y;
}
于 2015-03-24T03:45:22.593 に答える
0

些細なケースでは、2 の累乗の偶数倍であるすべての数値が左にシフトされます (これは、符号ビットを変更する可能性がある場合には当てはまりません)。

例えば

10100

は4回

101

と 10100

は2回

1010

他の倍数については、2 つのシフトの出力を組み合わせて見つける必要があります。コンピュータ分割の原始的な方法を調べたいと思うかもしれません。

x = a / b

のように実装

buffer = a
while a is bigger than b; do
  yes: subtract a from b
       add 1 to x
done

より高速なルーチンは、最初により高いレベルの場所の値を見つけようとし、多くの減算をスキップします。これらのルーチンはすべてビット単位で実行できます。しかし、それは大きな苦痛です。ALU では、これらのルーチンはビットごとに実行されます。より多くのアイデアを得るために、デジタル ロジック デザイン ブックを参照することをお勧めします。

于 2015-03-24T03:48:25.667 に答える
0

わかりましたので、コードのエラーが何であるかを発見しました。マスクを使用して数値が別の数値の倍数であるかどうかを計算することは不可能であると大多数が言うので、私が学んだことを共有すると考えました. 可能です!- 正しいデータ型を使用している場合。

上記のコードは、渡された x も unsigned long であったため、y が unsigned long 定数として宣言されている場合に機能します。重要な点は、長い部分や定数部分ではなく、数値が符号なしであることです。この符号ビットは、数字の最初の場所が符号を示し、ビットごとの演算を実行すると符号が混乱する可能性があるため、誤算を引き起こします。

したがって、16 の倍数を探している場合のコードは次のとおりです。 const unsigned long y = 16; //私の場合はグローバルに宣言

次に、unsigned long が次のコードを実行する関数に渡されます。 if(x&(y-1)){ //0 でない場合は y の倍数 x は、最も近い 16 の倍数のサイズになります。

于 2015-03-25T22:35:11.537 に答える