C#类似的按位运算导致不同的答案

时间:2018-12-10 16:57:41

标签: c# bit-manipulation bitwise-operators

我目前正在CS班上为一个项目编写解决方案,但结果却相互矛盾。

基本上,我必须从从文件读取的BYTE中读取单个BIT。

这些是相关的方法(忽略命名标准,我没有制造它们,我也讨厌它们):

function flatten<N extends NestedArray<any>>(arr: N): Array<NestedElementType<N>> {
  const ret: Array<NestedElementType<N>> = [];
  arr.forEach(l => {
    if (Array.isArray(l)) {
      ret.push(...flatten(l));
    } else {
      ret.push(l);
    }
  });
  return ret;
}

const flattened = flatten([["a"], ["b"], [[[[["c"]]], "d"]]]); // string[]

getbit()是我编写的方法,它可以正常工作。但是,我的第一个解决方案无效。

当输入文件包含“ ABC”时,通过一次读取1位,它可以正确输出static bool no_more_bytes() /**********************/ /*** NO MORE BYTES? ***/ /**********************/ { return (in_stream.PeekChar() == -1); } static byte read_a_byte() /********************************************************************************/ /*** Function to read a single byte from the input stream and set end_of_file ***/ /********************************************************************************/ { byte abyte; if (!no_more_bytes()) abyte = in_stream.ReadByte(); else { abyte = 0; end_of_file = true; } return abyte; } static byte getbit() /**********************************************************/ /*** Function to get a single BIT from the input stream ***/ /**********************************************************/ { byte mask; if (current_byte == 0 || current_bit_position == 8) { current_byte = read_a_byte(); current_bit_position = 0; } mask = current_bit_position; current_bit_position++; //Your job is to fill in this function so it returns //either a zero or a one for each bit in the file. bool set = (current_byte & (128 >> current_bit_position - 1)) != 0; // This is the line in question if (set) { return 1; } else { return 0; } } (65、66、67)。

但是,我最初的解决方案是

01000001 00100001 01100001

所以问题是:为什么将current_bit_position右移128而不是将current_bit_position左移1

1 个答案:

答案 0 :(得分:2)

我将把这个问题解释为一个关于位的顺序的问题,因为正如注释所建议的,在大多数情况下,期望对同一数据执行不同的操作返回相同的结果并没有多大意义。

那么为什么我们从128开始并向右移动而不是从1开始并向左移动呢?两种方法对于枚举字节中的每个位都是有效的,但是它们的操作顺序相反。

如果要向左移动1<<)而不是向右移动128>>),则必须将current_bit_position从7运行到0,而不是0到7。

移动1

  • 1 << 7 == 10000000
  • 1 << 6 == 01000000
  • 1 << 5 == 00100000
  • 1 << 4 == 00010000
  • 1 << 3 == 00001000
  • 1 << 2 == 00000100
  • 1 << 1 == 00000010
  • 1 << 0 == 00000001

移动128

  • 128 >> 0 == 10000000
  • 128 >> 1 == 01000000
  • 128 >> 2 == 00100000
  • 128 >> 3 == 00010000
  • 128 >> 4 == 00001000
  • 128 >> 5 == 00000100
  • 128 >> 6 == 00000010
  • 128 >> 7 == 00000001

由于我们通常表示数字的左边是最高有效位,右边是最低有效位,因此您需要使用上述序列以正确的顺序获取位。