在做我认为相同的计算时,我得到了不同的结果。我认为这是一个类型转换问题。
我从hardware sensor via I2C
提取温度值。 datasheet
表示进行转换的公式如下:
(((14_bit_ADC_value)/16382) * 165) - 40)
两个字节的ADC值存储在两个字符中,需要进行一些移位才能得到 14字节:
((((rawtemp[2] << 6 ) | (rawtemp[3] >> 2) / 16382) * 165) - 40);
问题:
我的代码是:
#include <stdio.h>
int main()
{
char rawtemp[4];
rawtemp[2] = 0x61; //example captured value
rawtemp[3] = 0x40; //example captured value
//method 1
float test = 0;
test = (rawtemp[2] << 6 ) | (rawtemp[3] >> 2);
test = test / 16382;
test = test * 165;
test = test - 40;
printf("test1: %f C\r\n", test); //This works.
//method 2
test = (((rawtemp[2] << 6 ) | (rawtemp[3] >> 2) / 16382) * 165) - 40;
printf("test2: %f C\r\n", test); //This does not work.
return 0;
}
输出:
$ ./k
test1: 22.688316 C
test2: 1024280.000000 C
为什么导出温度值的第二种方法失败?
答案 0 :(得分:4)
方法2中有两个错误:
(rawtemp[2] << 6 ) | (rawtemp[3] >> 2) / 16382
应为((rawtemp[2] << 6 ) | (rawtemp[3] >> 2)) / 16382
,因为按位OR的优先级低于除法。
在C中,如果'/'
的两个操作数都是int,结果也是int,或floor(a/b)
,则可以使用(float)((rawtemp[2] << 6 ) | (rawtemp[3] >> 2)) / 16382
(或将16382写为16382.0 )将一个操作数转换为float,然后结果也将是int。
答案 1 :(得分:2)
所以正确的method2
是:
test = ((((rawtemp[2] << 6 ) | (rawtemp[3] >> 2)) / 16382.0) * 165) - 40;
答案 2 :(得分:0)
另一种方法是将表达式//method 2
test = ((((float) ((rawtemp[2] << 6 ) | (rawtemp[3] >> 2))) / 16382) * 165) - 40;
的类型强制转换为
grep