我的代码依赖于uint16_t,int32_t/uint32_t和int64_t值的混合数据.它还包括一些较大的位移位常数(例如,1 << 23,偶数1 << 33).
在计算int64_t值时,如果我仔细地转换每个子部分(例如,将uint16_t值向上转换为int64_t)它可以工作 - 如果我不这样做,计算通常会出错.
我最终得到的代码如下:
int64_t sensDT = (int64_t)sensD2-(int64_t)promV[PROM_C5]*(int64_t)(1<<8);
temperatureC = (double)((2000+sensDT*(int64_t)promV[PROM_C6]/(1<<23))/100.0);
Run Code Online (Sandbox Code Playgroud)
不过,我想知道,如果我在这里撒上类型的石膏太杂乱而且太慷慨了.我不确定1 << 8是否需要演员(虽然没有一个,1 << 23不会导致错误的计算),但也许他们也这样做.对于像这样的计算的上升值,多少钱太多了?
编辑:所以很清楚,我问的是最小适当的投射量是什么 - 正确功能需要什么(为了清晰起见,可以添加更多的投射或修改器,但从编译器的角度来看,确保正确计算的必要性是什么?)
EDIT2:我使用C-风格转换,因为这是从一个Arduino型嵌入代码库(其本身使用的铸件这种风格的话).从具有期望效果的角度来看,它们看起来是等效的,因此我使用了现有的编码风格.
通常,只要每个运算符的一个操作数具有正确的大小,您就可以依赖整数提升来为您提供正确的操作.所以你的第一个例子可以简化:
int64_t sensDT = sensD2-(int64_t)promV[PROM_C5]*(1<<8);
Run Code Online (Sandbox Code Playgroud)
小心考虑优先级规则以了解运算符的应用顺序!
如果您要混合相同大小的有符号和无符号类型,则可能会遇到麻烦,尽管其中任何一种都应该提升为更大的签名类型.
你需要小心常量,因为没有任何装饰,这将是默认的整数大小和签名. 1<<8不会有问题,但1<<35可能会; 你需要1LL<<35.
如果有疑问,一些额外的演员或括号不会受到伤害.