替换32位数字的字节

时间:2012-04-12 22:41:33

标签: c

我有一个名为replaceByte(x,n,c)的函数,用n替换x中的字节c,但有以下限制:

  • 从0(LSB)到3(MSB)编号的字节
  • 示例:replaceByte(0x12345678,1,0xab) = 0x1234ab78
  • 您可以假设0 <= n&lt; = 3且0&lt; = c&lt; = 255
  • 法律操作:! ~ & ^ | + << >>
  • Max ops: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;
}

3 个答案:

答案 0 :(得分:7)

由于这看起来像家庭作业,我不打算发布代码,但列出了你需要执行的步骤:

  1. c转换为32位数字,以便在移位时不会丢失任何位
  2. 接下来,将c向右移动适当的位数(如果n==0没有移位,如果n==1移动8等等。)
  3. 创建一个32位的位掩码,将x的最低8位置零,然后将此掩码移动与上一步相同的量
  4. 对移位的位掩码执行按位AND,并xx
  5. 的相应位置零
  6. 执行移位c值和x的按位OR(或加法)以替换后者的屏蔽位

答案 1 :(得分:4)

啊......你快到了。

只需更改

return (mask & x) | shift; 

return (~mask & x) | shift;

mask应包含除要屏蔽的区域以外的所有区域,反之亦然。

我正在使用这个简单的代码,它在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;
}

答案 2 :(得分:2)

正确的解决方案也适用于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;
     }