有没有办法确保用户输入的浮点变量(小数点后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
返回值的技巧是什么?
答案 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 ++”,看看你如何比较两个浮点/双值。我希望能回答你的问题。