printf输出float和double类型数据的有关问题
printf输出float和double类型数据的问题
以前都一直以为printf输出double类型使用的是%lf,今天才发现输出float和double使用的都是%f。这让我很是迷惑。因为printf是变参函数,参数的入栈和出栈都是由被调用者完成。printf识别各个参数完全是通过输出格式字符串中获取要输出的参数的类型。float和double分别占用4和8个字节的空间,当printf看到%f的时候如何知道这个数据是几个字节呢?难道float类型在入栈的时候也是自动按照double来如栈吗?
如果各位有知道其中原因的,还望不吝赐教。
------解决方案--------------------
查MSDN得:
e double
E double
f double
g double
G double
所以,不是printf知道是什么类型,而是在输出时做了强制转换。
把float赋给double不会丢失精度一样。
------解决方案--------------------
应该是将%f转换成double再入栈
------解决方案--------------------
是因为使用了自动向上类型转换
------解决方案--------------------
5楼说的基本没错,只不过不是类型提升,而是usual arithmetic conversions。
可变参数函数一般不进行类型检查,但printf的float是个例外,float在入栈前先被转换为double,这是为了兼容K&R C的做法。
------解决方案--------------------
VC98\Include\STDARG.h对于系列变参宏的说明。
其际上,也确实如此,将float作为参数传递给变参函数,编译时,会自动将float的值转换为double,然后压入栈。
以前都一直以为printf输出double类型使用的是%lf,今天才发现输出float和double使用的都是%f。这让我很是迷惑。因为printf是变参函数,参数的入栈和出栈都是由被调用者完成。printf识别各个参数完全是通过输出格式字符串中获取要输出的参数的类型。float和double分别占用4和8个字节的空间,当printf看到%f的时候如何知道这个数据是几个字节呢?难道float类型在入栈的时候也是自动按照double来如栈吗?
如果各位有知道其中原因的,还望不吝赐教。
------解决方案--------------------
查MSDN得:
e double
E double
f double
g double
G double
所以,不是printf知道是什么类型,而是在输出时做了强制转换。
把float赋给double不会丢失精度一样。
------解决方案--------------------
应该是将%f转换成double再入栈
------解决方案--------------------
是因为使用了自动向上类型转换
------解决方案--------------------
5楼说的基本没错,只不过不是类型提升,而是usual arithmetic conversions。
可变参数函数一般不进行类型检查,但printf的float是个例外,float在入栈前先被转换为double,这是为了兼容K&R C的做法。
------解决方案--------------------
VC98\Include\STDARG.h对于系列变参宏的说明。
其际上,也确实如此,将float作为参数传递给变参函数,编译时,会自动将float的值转换为double,然后压入栈。
...
while ((ch = *format++) != _T('\0') && charsout >= 0) {
chclass = find_char_class(ch); /* find character class */
state = find_next_state(chclass, state); /* find next state */
/* execute code for each state */
switch (state) {
...
case ST_SIZE:
/* just read a size specifier, set the flags based on it */
switch (ch) {
#if !LONG_IS_INT
------解决方案--------------------
!defined (_UNICODE)
case _T('l'):
flags
------解决方案--------------------
= FL_LONG; /* 'l' => long int or wchar_t */
break;
#endif /* !LONG_IS_INT
------解决方案--------------------
!defined (_UNICODE) */
...
case ST_TYPE:
switch (ch) {