在C/C++中,混合型整数数学所需的最小类型上传是什么?

Mar*_*ver 8 c++

我的代码依赖于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型嵌入代码库(其本身使用的铸件这种风格的话).从具有期望效果的角度来看,它们看起来是等效的,因此我使用了现有的编码风格.

Mar*_*som 8

通常,只要每个运算符的一个操作数具有正确的大小,您就可以依赖整数提升来为您提供正确的操作.所以你的第一个例子可以简化:

int64_t sensDT = sensD2-(int64_t)promV[PROM_C5]*(1<<8);
Run Code Online (Sandbox Code Playgroud)

小心考虑优先级规则以了解运算符的应用顺序!

如果您要混合相同大小的有符号和无符号类型,则可能会遇到麻烦,尽管其中任何一种都应该提升为更大的签名类型.

你需要小心常量,因为没有任何装饰,这将是默认的整数大小和签名. 1<<8不会有问题,但1<<35可能会; 你需要1LL<<35.

如果有疑问,一些额外的演员或括号不会受到伤害.

  • @MartyMacGyver:你只需要施放一个,如第二个例子.通常当表达式变得混乱时,可以通过`static_cast`将cast _as作为一个单独的变量,这使得它明显清楚你正在投射什么以及它是否需要. (2认同)
  • @MartyMacGyver计算和赋值是完全独立的操作,因此赋值对计算没有影响.您甚至可以完全省略任务,以便计算转到从未使用过的临时结果!一个好的编译器会认识到它是死代码并优化它,但语法仍然允许它.这与函数的返回类型不是重载决策的一部分的原因相同. (2认同)