C中的所有东西都有一个类型,其中包括数字常量/文字,如3.0
.
3
的类型是int
.
3.0f
的类型是float
.
3.0
的类型是double
.
进而,float
和double
在某个系统上可能具有相同的精度,也可能不具有相同的精度.显然,double
在你的系统上有更高的精度,因此你会注意到不同之处.
关于implicit type promotions人的一些注意事项:
score1 + score2 + score3
都是int
类型,因此不会发生隐式提升,结果是int
.
将结果int
与另一个类型为float
的操作数放在一起的操作中,意味着在操作之前,int
将被提升为float
(根据"通常的算术转换",请参见上面的链接).
或者在3.0
的情况下,int
的结果将被提升到double
.
printf
和%f
所做的事情碰巧总是期望double
作为输入(%lf
也可以),如果您给它float
,它将被隐式地提升为double
,这是一个针对变量函数的奇怪规则,称为"默认参数提升".
但由于最后的类型升级发生在after,所以结果是计算出来的,这不会影响精度.
最佳实践:
- 对于类型要明确,并避免包含隐式提升的代码.
- 避免在同一表达式中混合使用
int
/float
/double
,因为这是众所周知的错误配方.坚持使用一种类型,并在需要的地方显式转换操作数.
例如,我会像这样重写您的代码:
(double)(score1 + score2 + score3) / 3.0
功能是100%等价的,但这是self 文档化的代码,不依赖于隐含的提升,比如"我知道我在做什么".
相反的--代码依赖于silent的隐性促销--说:"要么我知道我在做什么,依靠隐性促销,要么我不知道我在做什么,只是靠(坏)运气把这个表达弄对了/弄错了."