为什么有些人会在变量后面加上f呢?
How come some people append f to the end of variables?
在教程中,我正在阅读OGRE3d这里的程序员不断在他初始化的任何变量末尾添加f
,如200.00f
或0.00f
,所以我决定删除f
,看看它是否编译,它编译得很好,在变量末尾添加f
的意义是什么?
编辑:所以你说如果我用200.03
初始化一个变量,它不会初始化为一个浮点数,但如果我用200.03f
这样做,它会吗?如果不是,那么f在哪里有用呢?
这是一种指定数字必须被解释为"float"而不是"double"的方法(这是c++十进制数的标准,并且使用两倍的内存)。
这个讨论可能会有所帮助:
http://www.cplusplus.com/forum/beginner/24483/引自http://msdn.microsoft.com/en-us/library/w9bk1wcy.aspx
不带f、f、l或l后缀的浮点常量具有type翻倍。如果字母f是后缀,则常量具有类型自由浮动。如果以字母l或l作为后缀,则具有长双精度类型。为例子:
200.00f
不是变量。不能改变
这是一个编译时常数,用float
表示。f
表示它是float
。
通过比较,200.00
将被解释为double
。
C标准规定常量浮点数为双精度浮点数,从而将其提升为双精度浮点数。
float a,b,c;
...
a = b+7.1; this is a double precision operation
...
a = b+7.1f; this is a single precision operation
...
c = 7.1; //double
a = b + c; //single all the way
双精度需要更多的常量存储空间,加上变量操作数从单精度到双精度的转换,然后再从双精度到单精度的转换来赋值结果。所有的转换都在进行,如果你不知道浮点数是如何工作的,四舍五入等等,你可能得不到你想要得到的结果。编译器可能会在路径的某个点上优化一些这种行为,使其更难以理解真正的问题,并且硬件中的fpu可能接受混合模式操作数,也隐藏了真正发生的事情。
这不仅是速度问题,而且是准确性问题。最近有一个SO问题,几乎相同的问题,为什么这个比较适用于一个数字而不是另一个。以分数5/11为例0.454545....让我们假设,你有一个基数为10fpu,单精度为3位有效数字,双精度为6位有效数字。
float a = 0.45454545454;
...
if(a>0.4545454545) b=1;
...
在我们假设的系统中,我们只能在a中存储三位数字,所以a = .455,因为我们默认使用四舍五入模式。但是我们的比较将被认为是双重的,因为我们没有把f放在数字的末尾。双版本为0.454545。A被转换为double类型,结果为0.455000,因此:
if(0.455000>0.454545) b = 1;
0.455大于0.454545,所以b等于1。
float a = 0.45454545454;
...
if(a>0.4545454545f) b=1;
...
所以现在比较是单精度的,所以我们比较0.455和0.455,这不是更大的,所以b=1不会发生。
当你写以10为基数的浮点常量时,计算机中的浮点数是以2为基数的,它们并不总是平滑地转换,就像5/11在以11为基数的情况下可以正常工作,但在以10为基数的情况下,你会得到一个无限重复的数字。例如,十进制的0.1在二进制中创建一个重复的模式。根据尾数截断的位置,可以使尾数的lbit舍入或不舍入(还取决于您正在使用的舍入模式,如果您正在使用的浮点格式甚至有舍入)。哪一个本身就会产生问题,这取决于你如何使用变量,正如上面的比较所示。
对于非浮点数,编译器通常会保存你,但有时不会:
unsigned long long a;
...
a = ~3;
a = ~(3ULL);
...
根据编译器和计算机的不同,这两个赋值可能会给你不同的结果,一个可能会给你0x00000000fffffffffffffffc,另一个可能会给你0xfffffffffffc。
如果你想要特定的东西,你应该非常清楚地告诉编译器你想要什么,否则编译器会猜测,并不总是做出你想要的猜测。
表示该值将被解释为单精度浮点变量(类型为float
)。如果没有f后缀,它将被解释为双精度浮点变量(类型为double
)。
这样做通常是为了关闭编译器关于为float变量赋双精度值可能导致精度损失的警告。当你没有收到这样的警告时,你可能在编译器设置中关闭了警告(这很糟糕!)。
但它也可以有微妙的句法意义。正如你所知,c++允许函数具有相同的名称,但其参数类型不同。在这种情况下,f后缀可以确定调用哪个函数。
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 为什么我不能在一个类的不同行中声明和定义成员变量?
- 为什么我的变量没有更新,我的 LED 没有亮起?
- 你好。。。id_public变量不应该给出结果为 81 和 86 吗?为什么它为两个派生类占用不同的内存位置?
- 为什么C++有不同的变量初始化方式?
- 如果全局变量默认是外部变量,为什么要添加"extern"关键字?
- 为什么未命名的结构内联变量在每个翻译单元中没有相同的地址?
- 为什么我可以将变量存储在不是其最小对齐方式的倍数的地址?
- 为什么thread_local变量在这里从未初始化?
- 为什么内存屏障依赖于变量?
- 为什么我的变量存在于其范围之外
- 为什么我们再次从结构对象创建结构变量?
- 字符串与字符* 作为类成员变量.为什么要使用字符*
- 如何读取文件内容并将其保存到字符串类型变量?为什么有空白空间
- 将char * *变量赋值给char * const *变量——为什么允许这样做?
- 在类中传递私有变量——为什么不允许这样做
- 引用临时变量 - 为什么编译器没有检测到它?
- 访问类中的私有成员变量:为什么这样做
- 全局变量-C++为什么这种方式很危险
- ' ios_base '的标志都是静态const整型变量.为什么可以用' ios_base::setf() '来