9

バイトインを次の制限でreplaceByte(x,n,c)置き換えるという関数があります。nxc

  • 0 (LSB) から 3 (MSB) までの番号が付けられたバイト
  • 例:replaceByte(0x12345678,1,0xab) = 0x1234ab78
  • 0 <= n <= 3 および 0 <= c <= 255 と仮定できます
  • 法的操作:! ~ & ^ | + << >>
  • 最大操作: 10

    int replaceByte(int x, int n, int c) {
            int shift = (c << (8 * n));
            int mask = 0xff << shift;
            return (mask & x) | shift;
        }
    

しかし、テストすると、次のエラーが発生します。

エラー: テスト replaceByte(-2147483648[0x80000000],0[0x0],0[0x0]) に失敗しました... ...0[0x0] を返します。-2147483648[0x80000000] である必要があります

* が正当な演算子ではないことに気付いた後、私はついにそれを理解しました...そして、もし興味があれば、これが私がしたことです:

int replaceByte(int x, int n, int c) {
  int mask = 0xff << (n << 3);
  int shift = (c << (n << 3));
  return (~mask & x) | shift;
}
4

3 に答える 3

7

これは宿題のように見えるので、コードを投稿するつもりはありませんが、実行する必要がある手順をリストします。

  1. cシフト中にビットを失わないように、32 ビットの数値にキャストします。
  2. 次に、c適切なビット数だけ左にシフトします (シフトしn==0ない場合n==1、8 だけシフトする場合など)。
  3. の下位 8 ビットをゼロにする 32 ビットのビットマスクを作成し、xこのマスクを最後のステップと同じ量だけシフトします。
  4. シフトされたビットマスクのビットごとの AND を実行xし、適切なビットをゼロにします。x
  5. cシフトされた値のビットごとの OR (または加算) を実行xし、後者のマスクされたビットを置き換えます
于 2012-04-12T22:48:24.740 に答える
6

Ahh... You are almost there.

Just change

return (mask & x) | shift; 

to

return (~mask & x) | shift;

The mask should contain all ones except for the region to be masked and not vice versa.

I am using this simple code and it works fine in gcc

#include<stdio.h>

int replaceByte(int x, int n, int c) 
{
    int shift = (c << (8 * n));
    int mask = 0xff << shift;
    return (~mask & x) | shift;
}

int main ()
{

    printf("%X",replaceByte(0x80000000,0,0));

    return 0;
}
于 2012-04-13T03:11:58.663 に答える
3

適切な解決策は、c = 0 の場合も同様です。

     int replaceByte(int x, int n, int c)
     {
        int shift = 8 * n;
        int value = c << shift;
        int mask = 0xff << shift;

        return (~mask & x) | value;
     }
于 2019-04-15T03:20:45.017 に答える