这是:
int i = 100 * 0.6;
不正确吗?
int i = 100 * (0.6F);
我为这么简单的问题道歉,但我没有记住数据类型促销的所有规则,我不确定如何验证这一点。
答案 0 :(得分:14)
它可以有所作为。对于example:
int i = (1 << 24) + 3;
printf("%d\n", (int)(i * 0.6)); // 10066331
printf("%d\n", (int)(i * 0.6f)); // 10066332
原因是第一个的计算是双精度的,后者是单精度的。单精度不能表示大于1 << 24
的所有整数。
另一个example(由以下评论中的@EricPostpischil提供):
int i = 100;
printf("%d\n", (int)(i * 0.29)); // 28
printf("%d\n", (int)(i * 0.29f)); // 29
原因是双精度情况下的中间结果略低于29,因此被截断为28。
所以我建议允许双精度(即省略f
/ F
)(然后使用round()
而不是依赖于隐式截断),除非你有充分的理由不这样做。
答案 1 :(得分:5)
在这种特殊情况下,F
不是必需的。它只是将常量指定为类型float
而不是类型double
。
答案 2 :(得分:1)
第一个说,并减少到
i [int] = 100 [int] * 0.6 [double]
i [int] = 100.0 [double] * 0.6 [double]
i [int] = 60.0 [double]
第二个说
i [int] = 100 [int] * 0.6 [float]
i [int] = 100.0 [float] * 0.6 [float]
i [int] = 60.0 [float]
两者实际上是相同的,除非你特别关心浮动与双精度。
答案 3 :(得分:1)
在嵌入式系统上,除了精度和执行时间之外,差异可能也很大。 f后缀使得数字成为浮点常数,而不是其他人已经注意到的双精度浮点常数。
如果所有操作数都是浮点数,则使用单精度浮点数将执行数学运算。如果处理器具有单精度浮点单元,则计算可以使用它(取决于编译器选项)。
如果另一方面任何操作数是double,则计算以双精度进行。如果cpu只有单精度FPU,则意味着计算将使用SW库完成。在这种情况下,有问题的代码的执行时间会长几倍。
此类CPU的示例是ARM Cortex-M4F。
类似但不是那么激进的差异效应是在没有FPU的情况下。所有浮点运算都使用sw库。双精度需要更多时间。