首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >printf %f如何在32位浮点型上工作

printf %f如何在32位浮点型上工作
EN

Stack Overflow用户
提问于 2018-12-11 04:02:00
回答 2查看 976关注 0票数 2

%f printf格式代码指定为对double [source]类型的值进行操作。但是,一个简单的测试程序演示了它也可以与float类型的值一起使用。这是怎么回事?

整数类型(例如intlong long int)的等效情况“有效”,因为在小端机器上,32位整数的低位字节恰好与64位整数的低位字节重叠,所以只要高位是0,你就会得到“正确”的答案。

但这不可能是floatdouble的情况,因为浮点格式不能像这样互换。如果不将浮点值转换为另一种格式(相当复杂),您就无法将浮点值打印为双精度值。试图通过键入双关语来执行此操作将只会打印出垃圾。

最重要的是,printf是可变的。编译器在编译时不一定知道将使用什么格式说明符,只知道参数的类型。因此,我能猜测的唯一一件事是,传递给变量函数的所有float值都会无条件地升级为double。但让我难以置信的是,我竟然在不知道这一点的情况下用C语言编程这么久。

在这里,C是如何进行隐式强制的?

来源:

代码语言:javascript
复制
#include <stdio.h>
#include <math.h>

int main() {
  float x[2] = {M_PI, 0.0};
  printf("value of x: %.16e\n", x[0]);
  printf("size of x: %lu\n", sizeof(x[0]));

  double *xp = (double *)&x[0];
  printf("value of *xp: %.16e\n", *xp);
  printf("size of *xp: %lu\n", sizeof(*xp));

  double y = M_PI;
  printf("value of y: %.16e\n", y);
  printf("size of y: %lu\n", sizeof(y));

  int i[2] = {1234, 0};
  printf("value of i: %lld\n", i[0]);
  printf("sizeof of i: %lu\n", sizeof(i[0]));

  long long *ip = (long long *)&i[0];
  printf("value of i: %lld\n", *ip);
  printf("sizeof of i: %lu\n", sizeof(*ip));

  return 0;
}

输出:

代码语言:javascript
复制
value of x: 3.1415927410125732e+00
size of x: 4
value of *xp: 5.3286462644388174e-315
size of *xp: 8
value of y: 3.1415926535897931e+00
size of y: 8
value of i: 1234
sizeof of i: 4
value of i: 1234
sizeof of i: 8

编译命令和版本:

代码语言:javascript
复制
$ gcc test_float.c -o test_float
$ gcc --version
gcc (Ubuntu 5.5.0-12ubuntu1~16.04) 5.5.0 20171010
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-12-11 04:09:25

请参阅Variadic argumentsDefault argument promotions

在函数调用时,作为变量参数列表一部分的每个参数都会经历特殊的隐式转换,称为default argument promotions

类型的每个参数都经过整数提升(见下文),而类型的每个参数都隐式转换为类型double

票数 4
EN

Stack Overflow用户

发布于 2018-12-11 04:05:17

因此,我能猜测的唯一一件事是,传递给变量函数的所有浮点值都会无条件地升级为

是的--这是完全正确的。

来自C标准;

6.5.2.2.7函数原型声明程序中的省略符号会导致参数类型转换在最后声明的参数之后停止。默认参数提升是在尾随参数上执行的。

“默认参数提升”规则将float提升为double,相关部分为:

6.5.2.2.6如果表示被调用函数的表达式具有不包含原型的类型,则对每个参数执行整数提升,并将具有浮点型的参数提升为double。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53712797

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档