C:提取一组特定的位?需要帮助解释一个特定的例子

时间:2014-12-16 17:54:45

标签: c bit-manipulation

问题:

  

设备连接到可以返回各种设备的计算机   与天气有关的温度。 GetTemps函数返回   每日高温在20-29位,日常低温中   位10-19,当前温度位0-9,全部为10位   整数。在以下程序片段中,第8行和第9行是   不完整的。他们应该将高温存储在highTemp和   currTemp中的当前温度,这样的温度就可以了   在第10行打印。请完成第8行和第9行,并实现代码   有效地

#include <stdio.h>
// Line 1
// Line 2
int GetTemps(void);
// Line 3
// Line 4
int main( ) {
    // Line 5
    int w, highTemp, currTemp;
    // Line 6
    w = getTemps( );
    // Line 7
    highTemp = <QUESTION 1>
    // Line 8
    currTemp = <QUESTION 2>
    // Line 9
    printf ( "High: %d\nCurrent: %d\n", highTemp, currTemp)
    // Line 10
    return 0;
}

答案是

highTemp = w>>20
currtemp = w<<20
  

正确的右移(对于highTemp)和位掩码(对于lowTemp)   操作

由我的班级TA给出

有人可以向我解释这个答案吗?我想我理解高阶是如何w>>20,但如果w是一个30位int[30...0]那么就不会向左移位位向左移位10到0并且有效地乘以它是2 ^ 20?这对我来说似乎太大了。

编辑:确切答案: enter image description here

1 个答案:

答案 0 :(得分:4)

你的TA答案是对的。以下是解决问题的方法。

当多个字段打包成单个值时,最安全地隔离您想要的位(通过屏蔽)。例如,假设高温位于第20-29位,我们需要一个掩码来隔离这些位。

const int high_mask = 0x3FF00000;  // 10-bit integer in bits 20-29
const int high_bits = w & high_mask;  // select the bits we care about

要将其转换为温度,我们需要移位结果,使位20为位0。

const int high_temp = high_bits >> 20;  // shift them "down"

但这不完全正确!我们没有考虑负温度。算术右移将保留值的符号,但我们将高位(32位整数)归零。即使我们没有掩盖这些位,问题也没有说明那些顶部位是什么值,所以我们不应该做出假设。

考虑这个标志的最简单方法是首先向左移动,这样我们的最高位就位于最高位置。然后,我们在向右移动时,处理器将执行相应的符号扩展。假设int是32位......

const int high_temp = (high_bits << 3) >> 23;  // shift down, preserving the sign

请注意,右移值必须考虑我们先做的左移。

(从技术上讲,如果我们转移到顶部位,然后转向另一种方式来削减最低位,则不再需要屏蔽,但从概念上讲,它可以帮助理解。)

另请注意,按位运算符的优先级可能会令人惊讶。因此,如果您尝试将这些步骤组合到一个表达式中,则可能需要添加一些括号。

类似的过程可以提取当前温度(以及嵌入在较大整数类型中的任何int值)。你只需要调整常量。