C算术不同输出

时间:2015-11-08 08:07:30

标签: c

在做我认为相同的计算时,我得到了不同的结果。我认为这是一个类型转换问题。

我从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

为什么导出温度值的第二种方法失败?

3 个答案:

答案 0 :(得分:4)

方法2中有两个错误:

  1. (rawtemp[2] << 6 ) | (rawtemp[3] >> 2) / 16382应为((rawtemp[2] << 6 ) | (rawtemp[3] >> 2)) / 16382,因为按位OR的优先级低于除法。

  2. 在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