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

标签 c bit-manipulation

问题:

A device is connected to a computer that can return various temperatures related to the weather. The GetTemps function returns the daily high temperature in bits 20–29, the daily low temperature in bits 10–19, and the current temperature in bits 0–9, all as 10-bit integers. In the following program fragment, lines 8 and 9 are incomplete. They should store the high temperature in highTemp and the current temperature in currTemp, so that these temperatures can be printed in line 10. Please complete lines 8 and 9, and implement code efficiently

#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

The correct right shift (for highTemp) and bitmask (for lowTemp) operations.

我类助教给的

谁能给我解释一下这个答案?我想我明白 w>>20 有多高,但是如果 w 是 30 位 int[30...0] 那么向左移位不会将位 10 向左推到 0 并有效地将它乘以 2^20 吗?这对我来说似乎太大了。

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

最佳答案

你的助教的回答是错误的。这是解决问题的方法。

当多个字段被打包到一个值中时,最安全的做法是首先隔离您想要的位(通过屏蔽)。例如,假设高温在位 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 位为 int 位 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 值)。您只需调整常量即可。

关于C:提取一组特定的位?需要帮助解释一个特定的例子,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27510909/

相关文章:

带有二维数组问题的 C 游戏板

c - 如何理解TLS证书是PEM还是DER格式

c# - linq if 语句或存储过程 if 语句

C 位级整数到浮点转换意外输出

java - 反转 int 中的所有位并返回 int

c - 找到大于 n 的最小 2 次方

c - 在 C 或 CUDA 中使用 << 求幂

bit-manipulation - 如何实现逻辑移位的算术右移?

c - OpenSSL 上的 AES CTR 256 加密操作模式

'topper' 的冲突类型,brnchwise