为什么下面的两个printf
语句在(float)
强制类型转换存在时打印相同的值,而在它被删除时却不打印相同的值?
#include <float.h>
#include <stdio.h>
int main(void)
{
float eps = 1.0;
while ((float)(1 + eps/2.0) != 1.0)
eps /= 2.0;
printf("%e\n", eps);
printf("%e\n", FLT_EPSILON);
}
2条答案
按热度按时间bzzcjhmw1#
在编程语言中,C非常乐于在比您预期的更广泛的类型中进行算术运算。
在除法之前将
eps
转换为double
,因为数值常量2.0
的类型为double
。您可以通过编写2.0f
来避免这种情况,但即使这样,有一条规则说,只要选择被记录在案,编译器就被允许在double
甚至long double
中执行 * 所有 * 浮点运算。(C2011第5.2.4.2.2节第9段)对于
FLT_EVAL_METHOD == 0
的实现,可以通过编写以下代码来避免强制转换但如果
FLT_EVAL_METHOD
非零,则必须使用强制类型转换。nr9pn0ug2#
对于OP的代码,一个功能良好的编译器会报告如下内容
这就暗示了
float
和double
之间发生了一些事情。double
或更宽的中间数学**使用
double
常量或取决于FLT_EVAL_METHOD
,可能会产生各种结果。FLT_EVAL_METHOD == 2
表示可以使用long double
范围和精度完成中间FP数学运算。故事的寓意:使用浮点数时要小心。
FLT_EVAL_METHOD == 0
输出FLT_EVAL_METHOD == 2
输出舍入模式可能会影响事情,但我还没有一个样本来演示它。