【发布时间】:2018-08-04 11:04:20
【问题描述】:
如果我有
printf("%f\n", 3);
我明白了
3.000000
如果我有:
printf("%f\n", 3.0);
我得到了同样的答案。
但事情是这样的,3 和 3.0 应该是完全不同的,有点明智。
3.0 应该类似于 01000000010000000000000000000000 (但由于 vararg 函数中的隐式转换而双精度)
3 应该类似于00000000000000000000000000000011
3 在显示之前必须以某种方式转换为浮点数。
所以我的问题是,这是怎么做到的?编译器会以某种方式作弊吗?我将如何在我自己的变量 args 函数中实现这一点?
【问题讨论】:
-
它没有。
printf("%f\n", 3);是未定义的行为。 -
你用的是什么编译器?刚刚在onlinegdb.com/BymQYx1OG 尝试过,它输出 0.00000。但正如所说的那样,这是未定义的行为——这意味着编译器可以做它想做的事情,包括你所说的“作弊”,但这对于编译器为你“修复”损坏的代码来说是奇怪的(而且无益的)行为。将编译器警告级别设置为高。一些编译器可以选择显式测试标准函数的格式说明符,也可以将新函数添加到使用相同格式说明符的检查中。
-
哪个编译器在哪个平台上为整数
3生成3.000000?由于它是一个常数,编译器在编译时评估表达式的外部机会(不太可能,但几乎可能)。尝试使用整数变量而不是文字,您应该会得到不同的结果。 -
"我将如何在我自己的变量 args 函数中实现它?":你真的不想那样做!而是使用编译器的工具来验证格式说明符。
-
在 SO 的 cmets 中出现正确答案似乎很常见。谢谢!我在 Linux 上使用 GCC 7。我没有用另一个编译器尝试过。当我在 XV6 中重新实现 printf 的 %f 时,GCC 似乎不想再作弊了:/
标签: c floating-point printf