在阅读book about 3D graphics的一部分时,我遇到了以下任务:
const float vertexPositions[] = {
0.75f, 0.75f, 0.0f, 1.0f,
0.75f, -0.75f, 0.0f, 1.0f,
-0.75f, -0.75f, 0.0f, 1.0f,
};
为什么需要f后缀?可以从变量的类型中确定文字的类型吗?我相信没有f浮动文字被解释为双精度,但为什么当数组显然是float类型?
答案 0 :(得分:4)
您的示例中的float数组初始化在C中很好,就像它使用double
常量一样。对于手头的值,如果它是用double
常量初始化的float
数组也可以,因为手头的值可以完全表示为float
。即使在最后一种情况下,编译器也没有理由发出警告,尽管开发人员打算输入与最终类型不匹配的其他后缀会很奇怪和令人困惑。
简而言之,作者只是明确的,在float
数组的情况下,这是好的。
对于以十进制编写的任意值,您不希望使用float
常量初始化double
变量,因为“double-rounding”(其中单词“double”表示两次且未引用到同名的类型)。如果您按如下方式初始化f1
和f2
,则最终会得到不同的值,f1
实际上最接近预期值1.01161128282547:
float f1 = 1.01161128282547f;
float f2 = 1.01161128282547;
解释是,在f2
的情况下,小数值1.01161128282547 is first rounded到最近的double
,然后到最近的float
。这两个步骤引入的错误多于直接舍入到最近的float
,这就是f1
的初始化方式。
答案 1 :(得分:1)
一些术语的挑剔。
{}
(例如1.0f
)之间的内容不是文字,它们是常量。 C只有字符串文字和复合文字而且它就是它。在C 1.0
中是一个浮点常量。在C语言中,右侧(赋值或初始化)的类型决不会受左侧类型的影响。右侧的值的类型总是独立确定。它仅取决于如何指定该值。从不考虑左手边。然后,一旦知道右手大小的类型,原始值转换到左手侧的类型。换句话说,常量1.0
始终是double
类型的常量,即使您使用它来初始化float
对象。
使用double
常量(如1.0
)初始化float
类型的对象时,没有任何错误。如上所述,double
值将转换为float
类型。但是,某些编译器会发出有关该转换的警告,通知用户可能存在精度损失。具体来说,在初始化1.0f
个对象时,制服警告人们会使用显式浮动后缀(例如float
)或显式强制转换为(float) 1.0
(例如float
)。这看起来并不好,因为它违反了DRY(不要重复自己)规则,但在现实生活中,这种处理警告的方法经常遇到。
答案 2 :(得分:0)
虽然你可能没有因为省略f
而没有错误,但最好还是把它放在一起,原因有多种,例如:
float num = 0.1;
(num == 0.1)
评估将生成0
,因为num
四舍五入为0.1
为浮点数,而0.1
在表达式中为双倍。所以它们实际上并不相同,尽管看起来似乎是这样。
答案 3 :(得分:0)
不,永远不会推断文字的类型。没有f
它们是double
文字,并且指令是一个可能会失去精度的转换(在这种情况下并不是真的,因为所有的文字都用float来表示)。
如果你做了同样的警告
float x = 3.0;