这里的问题是您使用了一个float变量 ( gap),但您正在将它与一个double常量 ( 0.00002) 进行比较。该常量是double因为 C 中的浮点常量是双精度的,除非另有说明。
一个潜在的问题是该数字在或0.00002中均不可表示。(它根本不能用二进制浮点表示,因为它的二进制扩展是无限长的,就像 ⅓ 的十进制扩展一样。)所以当你在程序中编写时,C 编译器会用一个非常接近. 类似地,当将数字读入变量时,它会替换一个非常接近的值。由于数字的位数多于,因此该值比该值更接近。floatdouble0.00002double0.00002scanf0.00002floatfloat0.00002doublefloatsdouble0.00002float
当您比较具有不同精度的两个浮点值时,编译器会将精度较低的值转换为精度更高的完全相同的值。(可表示为的值集是可表示为的值double集的超集float,因此始终可以找到值与 adouble的值相同的 a 。)这就是执行float时发生的情况:转换为具有相同的值,并且与 double (close to) 进行比较。由于这两个值实际上都略小于 0.00002,并且更接近,所以小于。gap < 0.00002gapdouble0.00002doublefloatdouble
您可以通过多种方式解决此问题。首先,您可以通过制作gapadouble并将scanf格式更改为%lf或与gapa 进行比较来避免转换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.)
上述任何解决方案都将起作用。就个人而言,我会做gapadouble以使比较更直观,并将比较更改为与0.00001and进行比较1.0000。
顺便说一句,E-05后缀的意思是“乘以 10 的 -5 次方”(E代表Exponent)。你会看到很多;这是编写浮点常量的标准方法。