27 c c++ floating-point printf variadic-functions
从上一个问题:
如果你试图传递
float给printf它,它会double在printf收到它之前被提升
printf()是一个可变函数吧?可变参数函数在传递之前是否会提升float参数double?
Sha*_*our 26
是的,variadic函数的float参数被提升为double.
在C99标准草案部分6.5.2.2函数调用说:
[...]并且类型为float的参数被提升为double.这些被称为默认参数促销.[...]
从草案C++标准部分5.2.2函数调用:
[...]浮点类型受浮点提升(4.6)影响,参数值在调用之前转换为提升类型.[...]
和部分4.6:
float类型的prvalue可以转换为double类型的prvalue.该值保持不变
cppreference涵盖了C++中variadic函数的默认转换:
- std :: nullptr_t转换为void*
- float参数在浮点提升中转换为double
- bool,char,short和unscoped枚举转换为int或更宽的整数类型,如整数提升
我们可以在C中看到并且可能在C++中看到这种转换是为了与K&R C保持一致,来自Rationale for International Standard-Programming Languages-C(强调我的):
为了与过去的实践兼容,所有参数促销都在K&R中描述,如果没有原型声明,包括并不总是希望将float加倍.
Cor*_*lks 16
至于问题的部分原因,很简单:C(和C++)标准被认为double是"默认"浮点类型.不是float(这是我们许多程序员在使用浮点数时默认的).
通过观察可以看出:
3.14是一个double(如果你想要一个float,你必须采取额外的步骤并附加一个f)double默认sin()采用a (例如,取一个double;如果你想要一个float你必须使用sinf())有了这个,似乎更"自然",一个float将被提升到double一个可变参数函数调用,因为double是在语言的"自然"的默认.
250*_*501 14
给定函数原型,只有在尾随参数中使用时,类型float才会自动提升1.功能打印使用:
int printf(const char * restrict format, ...);
Run Code Online (Sandbox Code Playgroud)
1(引用自:ISO/IEC 9899:201x 6.5.2.2函数调用)
6.对每个参数执行整数提升,并将类型为float的参数提升为double.这些被称为默认参数促销.
7.默认参数提升是在尾随参数上执行的.
Bas*_*tch 11
有几个实用的原因:历史(C的第一个实现已用于系统编程,其中浮点运算无关紧要),以及在当前(平板电脑,台式机,服务器...)处理器,算术的事实操作double效率和效率一样高float(但是一些廉价的微控制器没有任何FPU,或者只能float通过硬件添加,并且每次操作都需要一个库double).最后,我想这样的规则可以实现稍微简单的调用约定和ABI.
想想float作为一个排序的short double(这当然是非法的C).A float主要用于需要压缩内存(并且可以承受精度损失)时非常有用.有关更多信息,请参见http://floating-point-gui.de/.
| 归档时间: |
|
| 查看次数: |
3193 次 |
| 最近记录: |