比较 C++ 中的两个浮点变量
Compare two float variables in C++
我已经阅读了多篇关于浮点变量比较的文章,但未能理解并从这些文章中获得所需的知识。所以,我在这里发布这个问题。
比较两个浮点变量的好方法是什么? 下面是代码片段:
#define EPSILON_VALUE 0.0000000000000001
bool cmpf(float A, float B)
{
return (fabs(A - B) < EPSILON_VALUE);
}
int main()
{
float a = 1.012345679, b = 1.012345678;
if(cmpf(a, b))cout<<"same"<<endl;
else cout<<"different"<<endl;
return 0;
}
输出:same
,尽管两个浮点变量保存不同的值。
没有通用的解决方案来比较包含先前操作错误的浮点数。必须使用的代码是特定于应用程序的。因此,要获得正确的答案,您必须更具体地描述您的情况。
根本问题是,使用不正确的数据执行正确的计算通常是不可能的。如果你想计算两个精确数学值x和y的函数,但你拥有的唯一数据是一些不精确计算的值x
和y
,通常不可能计算出完全正确的结果。例如,假设您想知道x+y的总和是多少,但您只知道x
是 3,y
是 4,但您不知道真实的、精确的x和y是什么。然后,您无法计算x+y。
如果您知道x
和y
大约是x和y,那么您可以通过添加x
和y
来计算x+y 的近似值。当正在计算的函数(在本例中+
)具有合理的导数时,工作:稍微改变具有合理导数的函数的输入会稍微改变其输出。当您要计算的函数具有不连续性或较大的导数时,此操作将失败。例如,如果要使用近似x
计算x的平方根(在实域中),但由于先前的舍入误差x
可能是负数,则计算sqrt(x)
可能会产生异常。同样,比较不等式或顺序是一个不连续的函数:输入的微小变化可以完全改变答案(从错误到真实,反之亦然)。
常见的坏建议是与"宽容"进行比较。此方法将假阴性(如果比较确切的数学值,则满足比较的数字的错误拒绝)换成误报(不正确接受不满足比较的数字)。
适用者是否可以容忍虚假接受取决于应用程序。因此,没有通用的解决方案。
要设置的容差级别,甚至计算容差的性质,都取决于数据、误差和先前的计算。因此,即使可以与公差进行比较,使用的公差量以及如何计算公差也取决于应用。没有通用的解决方案。
输出:相同,尽管两个浮点变量保存不同的值。
"浮点变量持有不同的值"是没有根据的。
打印same
是因为即使初始化常量不同,a,b
值也相同。
典型的float
是 32 位,可以表示大约 232个不同的值,例如 1.0、1024.0、0.5、0.125。 这些值的形式均为:+/- some_integer*2some_integer
1.012345679
和1.012345678
不在那个float
集中。 @Rudy维尔特胡伊斯。
1.012345 67165374755859375 // `float` member
1.012345 678
1.012345 679
1.012345 790863037109375 // `float` member
类似的情况也适用于double
,但精度更高 - 通常为64位。
1.012345679
和1.012345678
也不在该double
集中
1.012345 67799999997106397131574340164661407470703125 // `double` member
1.012345 678
1.012345 6780000001931085762407747097313404083251953125 // `double` member
...
1.012345 6789999998317597373898024670779705047607421875 // `double` member
1.012345 679
1.012345 67900000005380434231483377516269683837890625 // `double` member
可以将其视为四舍五入的 2 个步骤。 代码1.012345679
四舍五入到最接近的double
1.012345679000000005380434231483377516269683837890625。 然后,赋值将double
舍入到最接近的float
1.01234567165374755859375。
float a = 1.012345679;
// 'a' has the value of 1.01234567165374755859375
同样对于b
.代码1.012345678
四舍五入到最接近的double
1.012345677999999997106397131574340164661407470703125。 然后,赋值将double
舍入到最接近的float
1.01234567165374755859375。
flaot b = 1.012345678;
// 'b' has the value of 1.01234567165374755859375
a
和b
具有相同的值。
这是因为浮点数具有 7 位精度。 如果你想要更好的精度,你需要使用双倍或长双倍。
- 算术运算的结果类似于:C浮点变量中的1/3
- 为什么将两个浮点数相加会得到一个整数C++?
- 是否可以在 for 循环中添加两个浮点数?
- 如何获取两个时间点之间的时间
- 在浮点精度成为一个问题之前,可以将多少个浮点值加在一起
- 从数组中的文件读取多个浮点值
- 为什么双精度引用值在分配给C++中的浮点变量时不会更改
- 为什么我不能使用最小和最大这两个词作为变量名称?
- 在不使用 * 和 / 运算符的情况下将两个浮点数相乘和除以
- 是否可以保证浮点变量的副本将按位等效于原始副本?
- 直接为浮点变量分配十六进制整数与通过指针转换分配之间的区别
- 为什么将浮点变量与另一个浮点变量的缩减为int给出了完全不同的答案
- 如何线性化两个浮点变量的乘积
- 在不同翻译单元中具有静态存储持续时间的依赖非局部常量浮点变量的常量初始化
- 比较 C++ 中的两个浮点变量
- 两个浮点无限价值的QCOMPARE
- 当两个整数相乘并将结果存储在浮点变量中时,结果是否可以流动
- 从两个浮点向量生成哈希的最佳方法
- 在哪种情况下,我可以在C++中使用==直接比较两个浮点变量
- 如果我对浮点变量使用malloc和calloc,并将其赋值为int,那么剩下的2个字节会发生什么呢?