问题:
设备连接到可以返回各种设备的计算机 与天气有关的温度。 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?这对我来说似乎太大了。
编辑:确切答案:
答案 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值)。你只需要调整常量。