Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
浮点变量不符合条件(C)_C_Variables_Floating Point_While Loop - Fatal编程技术网

浮点变量不符合条件(C)

浮点变量不符合条件(C),c,variables,floating-point,while-loop,C,Variables,Floating Point,While Loop,我试图让用户输入一个介于1.00000到0.00001之间的数字,而边不包含在浮点变量中。我可以假设用户在点后键入的数字不超过5个。 下面是我写的: printf("Enter required Leibniz gap.(Between 0.00001 to 1.00000)\n"); scanf("%f", &gap); while ((gap < 0.00002) || (gap > 0.99999)) { printf("Enter required Leibniz g

我试图让用户输入一个介于1.00000到0.00001之间的数字,而边不包含在浮点变量中。我可以假设用户在点后键入的数字不超过5个。 下面是我写的:

printf("Enter required Leibniz gap.(Between 0.00001 to 1.00000)\n");
scanf("%f", &gap);
while ((gap < 0.00002) || (gap > 0.99999))
{
printf("Enter required Leibniz gap.(Between 0.00001 to 1.00000)\n");
scanf("%f", &gap);
}
现在,当我输入尽可能小的数字时:0.00002在while循环中卡住。 当我运行调试器时,我看到0.00002与这个值一起存储在浮点变量1.9999995E-005中 谁能帮我澄清我做错了什么?为什么0.00002不符合条件?这是什么1.9999995e-005。

浮点数不能存储0-1之间每个可能数的精确值,因此不可能。将0.00002分配给浮点将有一个不同但非常接近的数字,这是由于您正在经历的实现。随着数字的增加,精度降低

所以,你不能直接比较两个接近的浮动并得到健康的结果

可以找到有关浮点的更多信息

您可以做的是模拟定点数学。具有整数n=100000;表示1.00000内部1000->0.001等,并进行相应的计算或使用定点数学库。

浮点不能存储0-1之间的每个可能数的精确值,因此不可能。将0.00002分配给浮点将有一个不同但非常接近的数字,这是由于您正在经历的实现。随着数字的增加,精度降低

所以,你不能直接比较两个接近的浮动并得到健康的结果

可以找到有关浮点的更多信息


您可以做的是模拟定点数学。具有整数n=100000;表示1.00000内部1000->0.001等,并进行相应计算或使用定点数学库。

单精度浮点数的分数部分可以表示-2到2-2^-23之间的数字,并且具有最小量化步长为2^-23的分数部分。因此,如果某个值不能用该步骤表示,则根据以下公式用最近的值表示:

第一个变量等于1.999969797×10⁻⁵ 十进制格式,第二个等于1.99999948×10⁻⁵ 只是比较一下——如果我们选择5497560,我们得到2.000000677×10⁻⁵. 因此,可以选择第二个变量,其值不等于0.00002。 浮点数的总精度取决于指数值,取值范围为-128到127:它可以通过分数部分量化步长与指数值相乘来计算。在0.00002的情况下,总精度为2^-23×2^-15=3.6×10^-12。这意味着,如果我们将一个小于该值一半的值添加到0.00002,则0.00002保持不变。一般来说,它意味着有意义的浮点数的数量是从1×指数到2×10^-23×指数。
这就是为什么一种非常流行的方法是使用大于量化步长的ε值来比较两个浮点数

单精度浮点数的分数部分可以表示-2到2-2^-23之间的数字,并且具有最小量化步长为2^-23的分数部分。因此,如果某个值不能用该步骤表示,则根据以下公式用最近的值表示:

第一个变量等于1.999969797×10⁻⁵ 十进制格式,第二个等于1.99999948×10⁻⁵ 只是比较一下——如果我们选择5497560,我们得到2.000000677×10⁻⁵. 因此,可以选择第二个变量,其值不等于0.00002。 浮点数的总精度取决于指数值,取值范围为-128到127:它可以通过分数部分量化步长与指数值相乘来计算。在0.00002的情况下,总精度为2^-23×2^-15=3.6×10^-12。这意味着,如果我们将一个小于该值一半的值添加到0.00002,则0.00002保持不变。一般来说,它意味着有意义的浮点数的数量是从1×指数到2×10^-23×指数。
这就是为什么一种非常流行的方法是使用大于量化步长的ε值来比较两个浮点数

正如一些评论所说,由于浮点数的表示方式,您将看到类似这样的错误。 解决方法是将其转换为

gap + 1e-8 < 0.0002 

这为您提供了一个足够小的公差窗口,允许大多数情况下您希望通过,而大多数情况下您不希望失败

正如一些评论所说,由于浮点数的表示方式,您将看到这样的错误。 解决方法是将其转换为

gap + 1e-8 < 0.0002 

这为您提供了一个足够小的公差窗口,允许大多数情况下您希望通过,而大多数情况下您不希望失败这里的问题是您使用的是浮动变量间隙,但您将其与双常数0.00002进行比较 . 该常量是双精度的,因为C中的浮点常量是双精度的,除非另有规定

一个根本问题是数字0.00002不能以浮点或双精度表示。它根本不能用二进制浮点表示,因为它的二进制扩展是无限长的,就像&frac13;的十进制扩展一样;。因此,当您在程序中写入0.00002时,C编译器将其替换为非常接近0.00002的双精度值。类似地,当scanf将数字0.00002读入浮点变量时,它将替换非常接近0.00002的浮点值。由于双精度数字的位数多于浮点数,因此双精度值比浮点数更接近0.00002

比较两个精度不同的浮点值时,编译器会将精度较低的值转换为精度较高的完全相同的值。可表示为double的值集是可表示为float的值集的超集,因此始终可以找到其值与float值相同的double。这就是执行gap<0.00002时发生的情况:gap被转换为相同值的双精度,并与接近0.00002的双精度进行比较。由于这两个值实际上都略小于0.00002,且double更接近,因此浮点值小于double

你可以用几种方法解决这个问题。首先,您可以通过将gap设置为双精度并将scanf格式更改为%lf,或者将gap与浮点进行比较来避免转换:

假设您将间隙保持为浮动

上述任何一种解决方案都会奏效。就我个人而言,为了使比较更直观,我会将gap设置为double,并将比较改为0.00001和1.0000


顺便说一句,E-05后缀表示十乘以-5的幂,E代表指数。你会看到很多;这是一种写入浮点常量的标准方法。

这里的问题是使用浮点变量间隙,但将其与双常量0.00002进行比较。该常量是双精度的,因为C中的浮点常量是双精度的,除非另有规定

一个根本问题是数字0.00002不能以浮点或双精度表示。它根本不能用二进制浮点表示,因为它的二进制扩展是无限长的,就像&frac13;的十进制扩展一样;。因此,当您在程序中写入0.00002时,C编译器将其替换为非常接近0.00002的双精度值。类似地,当scanf将数字0.00002读入浮点变量时,它将替换非常接近0.00002的浮点值。由于双精度数字的位数多于浮点数,因此双精度值比浮点数更接近0.00002

比较两个精度不同的浮点值时,编译器会将精度较低的值转换为精度较高的完全相同的值。可表示为double的值集是可表示为float的值集的超集,因此始终可以找到其值与float值相同的double。这就是执行gap<0.00002时发生的情况:gap被转换为相同值的双精度,并与接近0.00002的双精度进行比较。由于这两个值实际上都略小于0.00002,且double更接近,因此浮点值小于double

你可以用几种方法解决这个问题。首先,您可以通过将gap设置为双精度并将scanf格式更改为%lf,或者将gap与浮点进行比较来避免转换:

假设您将间隙保持为浮动

上述任何一种解决方案都会奏效。就我个人而言,为了使比较更直观,我会将gap设置为double,并将比较改为0.00001和1.0000


顺便说一句,E-05后缀表示十乘以-5的幂,E代表指数。你会看到很多;这是写入浮点常量的标准方法。

间隙的类型是什么?您的条件与用户说明不匹配!0.00001<0.00002提示中的范围与您要检查的数字不一致。0.00002不是0.00001的直接继承人;他们之间有很多价值观。一旦你解决了这个问题,你会发现值0.00001不能用二进制浮点来精确表示。为什么不用gap=1.0呢?1.9999995e-005表示1.9999995*10^-5。这就是浮点数在计算机中的表示方式:指数从1到2,尾数幂为10。因此,您无法以二进制格式准确地表示某些数字,因此您会丢失一些数据,并且在您的情况下,舍入的数字不符合您的条件差距的类型是什么?您的条件与您的用户说明不匹配!0.00001<0.00002提示中的范围与您要检查的数字不一致。0.00002不是最佳值
0.00001的直接继承人;他们之间有很多价值观。一旦你解决了这个问题,你会发现值0.00001不能用二进制浮点来精确表示。为什么不用gap=1.0呢?1.9999995e-005表示1.9999995*10^-5。这就是浮点数在计算机中的表示方式:指数从1到2,尾数幂为10。因此,您无法以二进制格式准确地表示某些数字,因此会丢失一些数据,在您的情况下,舍入的数字不符合您的条件。浮点值是精确的值。这是一个不精确的操作。从字符串(如0.00002)到浮点通常以不精确的转换结束,而不是不精确的浮点结果。浮点是精确的值。这是一个不精确的操作。从字符串(如0.00002)到浮点通常以不精确的转换结束,而不是不精确的浮点结果。FLT_EPSILON值是从1.0f开始的量化步长。从2.0f开始的量化步骤是FLT_EPSILON*2.0f,等等@chux感谢您的评论。为我的答案添加了更多细节。FLT_ε值是从1.0f开始的量化步长。从2.0f开始的量化步骤是FLT_EPSILON*2.0f,等等@chux感谢您的评论。在我的回答中添加了更多细节。
while (gap < 0.00002F || gap > 0.99999F) {
while (gap <= 0.00001F || gap >= 1.0000F) { ...