这里的问题是您使用了一个float
变量 ( gap
),但您正在将它与一个double
常量 ( 0.00002
) 进行比较。该常量是double
因为 C 中的浮点常量是双精度的,除非另有说明。
一个潜在的问题是该数字在或0.00002
中均不可表示。(它根本不能用二进制浮点表示,因为它的二进制扩展是无限长的,就像 ⅓ 的十进制扩展一样。)所以当你在程序中编写时,C 编译器会用一个非常接近. 类似地,当将数字读入变量时,它会替换一个非常接近的值。由于数字的位数多于,因此该值比该值更接近。float
double
0.00002
double
0.00002
scanf
0.00002
float
float
0.00002
double
floats
double
0.00002
float
当您比较具有不同精度的两个浮点值时,编译器会将精度较低的值转换为精度更高的完全相同的值。(可表示为的值集是可表示为的值double
集的超集float
,因此始终可以找到值与 adouble
的值相同的 a 。)这就是执行float
时发生的情况:转换为具有相同的值,并且与 double (close to) 进行比较。由于这两个值实际上都略小于 0.00002,并且更接近,所以小于。gap < 0.00002
gap
double
0.00002
double
float
double
您可以通过多种方式解决此问题。首先,您可以通过制作gap
adouble
并将scanf
格式更改为%lf
或与gap
a 进行比较来避免转换float
:
while (gap < 0.00002F || gap > 0.99999F) {
但这并不完全正确,有几个原因。首先,实际上并不能保证 C 编译器所做的浮点转换与标准库 ( scanf
) 所做的转换相同,标准允许编译器使用“最接近的可表示值,或者更大与最近的可表示值紧邻的较小可表示值,以实现定义的方式选择。” (它也没有详细说明scanf
产生哪个值,但建议它是最接近的可表示值。)碰巧,gcc
和glibc
(Linux 上使用的 C 编译器和标准库)都产生最接近的可表示值,但其他实现不。
无论如何,根据您的错误消息,您希望该值介于0.00001
和之间1.00000
。所以你的测试应该是这样的:
while (gap <= 0.00001F || gap >= 1.0000F) { ...
(假设您保留gap
为float
.)
上述任何解决方案都将起作用。就个人而言,我会做gap
adouble
以使比较更直观,并将比较更改为与0.00001
and进行比较1.0000
。
顺便说一句,E-05
后缀的意思是“乘以 10 的 -5 次方”(E
代表Exponent
)。你会看到很多;这是编写浮点常量的标准方法。