如何确保以2位小数输入的浮点变量保留其精确值

时间:2016-07-25 19:10:03

标签: c floating-point rounding

有没有办法确保用户输入的浮点变量(小数点后2位小数)保留其精确值,而不是丢失精度?

这是一个示例案例: 我想在小数点后用50个数字围绕float,就像这样

  

在舍入= 0.70999997854232788085937500000000000000000000000000

之前

到此:

  

舍入后= 0.71000000000000000000000000000000000000000000000000

当我想在这样的条件下比较float数字时,我感到很困惑:

  

==程序开始==
  输入:0.71

/* program logic */
if (input == 0.71) {
    printf("True !");     
} else {
    printf("False !");
}
  

输出:错误!
  ==程序结束==

输出为False !且始终为False !,因为用户输入的真实值为0.70999997854232788085937500000000000000000000000000,而不是0.71000000000000000000000000000000000000000000000000

有没有办法像这样绕float值?我在这里读到浮点不准确的可能性:

然而,这些不回答我的问题。如果我使用ceilf(input * 100) / 100函数,当0.71 d使用0.71000格式时,它会将输入printf()变为%.5f - 这似乎有效。但是当我使用%.50f打印时,实际输入值显示为0.709999978542327880859375。所以,在我的情况下,我无法与该值进行比较。

因此,如果浮点数永远不准确,那么上述程序逻辑在该条件下获得true返回值的技巧是什么?

4 个答案:

答案 0 :(得分:4)

所有用户的输入都以文本的形式出现。检查它的最简单 - 也可能是最安全的方法 - 是在将其转换为数字之前将其作为字符串进行比较:

if (strcmp("0.71", input) == 0) {
    printf("True !");
} else {
    printf("False !");
}

当然,如果你想检查平等以外的东西,这可能是你不能接受的:)

另一点是你对 fixed 感兴趣,而不是在这里浮动数字 - 但是它们与实际整数混淆。如果您希望使用百分之一,那么使用百分数的整数 ...例如,考虑钱 - 而不是使用float(或{{1存储美元的金额(如$ 7.61),使用double(或上帝保佑你,int)存储美分 (如¢761)。

同样,对于另一个例子,如果你计算时间并且需要千分之一秒的精度,那么使用整数毫秒,而不是浮点数秒。

这将完全回避您的整个问题,也可能使您的程序更快......

答案 1 :(得分:3)

您可以根据自己的经验测试相等的范围。 只需用:

重写你的相等测试
if(input <= .71 + EPSILON && input >= .71 - EPSILON) {
}

在这里,您可以根据容差创建自己的EPSILON,或者也可以使用#include<cfloat>中的FLT_EPSILON表示C ++或#include <float.h>表示C.

回想一下,浮点数没有50位小数精度。因此,尝试在小数点后50位进行舍入并不能很好地解决问题。浮点数大约有6个(有时更多)精度。

答案 2 :(得分:3)

我确定此问题之前已得到解答,但是:

float rounded_down = floorf(input * 100) / 100;   /* Result: 0.70 */
float nearest = roundf(input * 100) / 100;  /* Result: 0.71 */
float rounded_up = ceilf(input * 100) / 100; /* Result: 0.71 */

这个函数所属的库我认为是math.h。

答案 3 :(得分:-2)

浮动和双打不准确。你不能使用相等比较float / double。即使在四舍五入之后你也永远不会比较浮动/双打。你总是用epsilon检查它们。尝试在谷歌中搜索“epsilon c ++”,看看你如何比较两个浮点/双值。我希望能回答你的问题。