C编程:当混合数据类型相乘时,float总是自动转换为double吗?
在Steven Prata的书“C Primer Plus”中,有一个关于类型转换的部分,其中“基本规则”部分已在规则1中说明:
Under K&R C, but not under current C, float is automatically converted to double.
http://www.9wy.net/onlinebook/CPrimerPlus5/ch05lev1sec5.html
有人可以解释but not under current C
意味着什么but not under current C
吗? 是否有自动转换的C版本和不自动转换的版本?
我正在尝试理解如果我有一个混合浮点数和双精度数的表达式,我可以依靠C来推动浮点数在评估时加倍吗?
它必须引用float * float
格式的二进制算术运算的结果。 在预标准版本的C操作数中,这些表达式被提升为double
,结果为double
类型。
例如,这里是“C参考手册”的引用
如果两个操作数都是int或char ,则结果为int 。 如果两者都是float或double ,结果是double 。
在C89 / 90中已经改变了这种行为并且float * float
表达式产生了float
结果。
- 如果任一操作数的类型为long double ,则另一个操作数将转换为long double
- 否则,如果任一操作数为double ,则另一个操作数将转换为double 。
- 否则,如果任一操作数为float ,则另一个操作数将转换为float 。
看看整个规则:
当出现在表达式中时,
char
和short
(有signed
和unsigned
)将自动转换为int
或者,如果需要,转换为unsigned int
。 (如果short
与int
大小相同,则unsigned short
大于int
;在这种情况下,unsigned short
将转换为unsigned int
。)在K&R C下,但不在当前C下,float
会自动转换为double
。 因为它们是更大类型的转换,所以它们被称为促销。
如果我们考虑整数类型,当它们出现在例如算术表达式中时,它们仍然被提升,因此在理论上没有算术 – 在char
或short
类型上执行,但是所有类型都是int
, unsigned int
或具有更高转换级别的类型(在as-if规则下,如果实现可以保证结果与实际执行促销的结果相同,则如果平台提供指令,则可以在较小类型下执行算术运算)。
用于保持float
的类似,在旧的预标准规则下, float
被提升为所有算术等的double
。
不再是这种情况, float
运算不涉及标准化C下的自动提升。
在具有混合类型的表达式中,通常所有内容仍然被提升为最大的涉及类型,因此如果将float
与double
进行比较或添加,则在操作之前将float
转换为double
。
是的,你可以依靠C来评估浮动加倍。
708 Otherwise, if the corresponding real type of either operand is double, the other operand is converted, without change of type domain, to a type whose corresponding real type is double.
我正在使用此处找到的文档。
对不起,我之前提到了错误的事情
是的,有不同版本的C,就像大多数软件产品的版本不同一样。
K&R是Brian K ernighan 和 Dennis R itchie在他们的书“ The C Programming Language”中描述的原始版本。
第一个标准化版本是ANSI C或C89,从那以后出现了几个新版本。 “当前C”可以表示C11(最新版本)或C99(可能是今天最多的usad版本)。
多年来,C语言定义已经多次标准化和修改。 C的原始(非标准化)版本被称为“K&R C”; 这是Kernighan和Ritchie最初开发的语言。
1989年,ANSI创建了一份官方标准文件(由ISO于1990年采用)来定义语言,并且在该标准中,一些事情被改变和扩展; 其中一个变化是删除了从float
到double
的自动升级。
从那时起,该标准进行了两次修订,一次是1999年,一次是2011年。
我正在尝试理解如果我有一个混合浮点数和双精度数的表达式,我可以依靠C来推动浮点数在评估时加倍吗?
这是现行标准的规则:
6.3.1.8通常的算术转换
…
首先,如果任一操作数的相应实数类型是long double
,则另一个操作数在不改变类型域的情况下被转换为其对应的实类型为long double
类型。否则,如果任一操作数的对应实数类型为
double
,则将另一个操作数转换为对应的实类型为double
的类型,而不更改类型域。否则,如果任一操作数的相应实数类型为
float
,则另一个操作数在不更改类型域的情况下转换为对应的实类型为float
类型。 62)
62)例如,添加
double _Complex
和float
只需要将float
操作数转换为double
(并产生double _Complex
结果)。
所以基本上,如果你有一个具有两种不同类型的表达式,那么具有更窄/更不精确类型的操作数将被提升为具有更宽/更精确类型的操作数的类型。