C 比较浮点数
在你认为我在问同一个N%的问题之前,请先阅读并注意 我正在做一个项目,在这个项目中,我有更多的函数返回double,它们中的一些可能是相同的,这在我的项目中是一件好事,如果是真的,那么我需要一个C 比较浮点数,c,C,在你认为我在问同一个N%的问题之前,请先阅读并注意 我正在做一个项目,在这个项目中,我有更多的函数返回double,它们中的一些可能是相同的,这在我的项目中是一件好事,如果是真的,那么我需要一个double比较,看看它们是否相等 我知道如果(x==y)进行等式比较不是一件聪明的事情,我们不需要说明原因,但我们可以检查,这是问题的一部分 语言(标准)是否保证比较为100% 如果是,则可以使用以下程序: #include <stdio.h> int main(void){ do
double
比较,看看它们是否相等
我知道如果(x==y)进行等式比较不是一件聪明的事情,我们不需要说明原因,但我们可以检查
,这是问题的一部分
语言(标准)是否保证比较
为100%
如果是,则可以使用以下程序:
#include <stdio.h>
int main(void){
double x = 3.14;
double y = 3.14;
if( x < y || x > y){
/* Are not Equal */
}else{
/* Are Equal, foo() will be called here\n" */
foo(x, y);
}
}
#包括
内部主(空){
双x=3.14;
双y=3.14;
if(xy){
/*他们不平等*/
}否则{
/*如果相等,将在此处调用foo()\n“*/
foo(x,y);
}
}
foo(x,y);
得到执行了吗?因为x
和y
在这里应该相等
编辑:
这个问题并不寻求一种比较两个double的方法,只是我应该使用,还是不应该使用而不是==\35; include
#include <stdio.h>
int main(void){
double x = 3.14;
double y = 3.14;
if( x < y || x > y){
/* Are not Equal */
}else{
/* Are Equal, foo() will be called here\n" */
printf("yes");
}
}
内部主(空){
双x=3.14;
双y=3.14;
if(xy){
/*他们不平等*/
}否则{
/*如果相等,将在此处调用foo()\n“*/
printf(“是”);
}
}
是的
我知道如果(x==y)进行等式比较不是一件聪明的事情
这根本不是事实。根据具体问题的不同,这可能是正确的做法,也可能是错误的做法
if (x < y || x > y)
与之相反的是
if (x == y)
一个错了,另一个也错了。一个是对的,另一个也是对的。用
符号而不是==
或编写相等条件=代码>不会突然让它变得更聪明
[1] 除非其中一个操作数是NaN。如果希望分数相等,则必须使用epsilon比较(即,检查数字在特定阈值内是否足够接近),或者非常小心地使用某些定点算法以避免舍入错误
是的,同样的问题已经被问了很多次了:
您需要更多地阅读比较是如何工作的,特别是为什么浮点相等不起作用。这不是equals运算符本身的问题,正如您所想(对于算术类型[当没有像NaN这样的特殊值时],!(x>y | | y>x)
将始终与x==y
相同。事实上,大多数编译器将xy
优化为x!=y
),而是因为舍入误差首先是浮点运算的一个基本部分x==y
确实适用于浮点类型,并且您可以自由地进行操作。在您执行任何算术运算,然后想要比较它们之后,这就成了一个问题,因为舍入误差的作用是不可预测的
所以本质上,是的。除非你真的在用双打做任何事情,否则你可以随心所欲地比较平等。如果您只是将它们用作索引或类似的东西,只要您知道正在为它们分配相同的值,就不会有问题。使用布尔标识不会使您脱离浮点数的基本功能。首先,您的条件设置有点不合适。要检查所需的不相等项
( x < y || y < x)
我所知道的二重相等的最佳实践是检查某个ε内的紧密度
eps = 0.00000000001
if( abs( x - y ) < eps ) {
printf("EQUAL!");
}
eps=0.00000000001
如果(abs(x-y)
有些是一样的。。。如果是真的,那么我需要一个双重比较,看看它们是否相等
OP正在质疑两种不同的测试FP平等性的方法,并想知道它们在功能上是否相同
除了可能的NaN,它不是由C定义的(但由定义的很好),这两个比较都是相似的,但是不符合圆锥等价性测试
考虑这个double
代码:
if (a==b) {
double ai = 1.0/a;
double bi = 1.0/b;
printf("%d\n", ai == bi);
} else {
printf("%d\n", 1);
}
结果是否总是“1”
?下面是一个例外(鼠标悬停查看)
< >代码> a=0;b=-0.0
。两者都相等,但它们的反比通常不相同。一个是正无穷大,另一个是负无穷大
问题归结到你需要多大程度的平等?什么是重要的?使用memcmp(&a,&b,sizeof a)
无疑是一个很强的测试,对于某些系统来说可能太强了,FP编号可能具有相同的非零值,但编码不同。如果这些差异很重要,或者只是上述例外情况,则由OP决定
如果测试2个不同的代码/函数产生相同的结果,请考虑对它们的差异进行评分。类似于以下内容:将
无符号长ULP_diff()
与0、1或2进行比较。取决于您的容错能力
// not highly portable
#include <assert.h>
unsigned long long ULP(double x) {
union {
double d;
unsigned long long ull;
} u;
assert(sizeof(double) == sizeof(unsigned long long));
u.d = x;
if (u.ull & 0x8000000000000000) {
u.ull ^= 0x8000000000000000;
return 0x8000000000000000 - u.ull;
}
return u.ull + 0x8000000000000000;
}
unsigned long long ULP_diff(double x, double y) {
unsigned long ullx = ULP(x);
unsigned long ully = ULP(y);
if (x > y) return ullx - ully;
return ully - ullx;
}
//可移植性不高
#包括
无符号长ULP(双x){
联合{
双d;
无符号长-长循环;
}u;
断言(sizeof(double)=sizeof(unsigned long-long));
u、 d=x;
如果(单位:0x80000000000000){
u、 ull^=0x80000000000000;
返回0x80000000000000-u.ull;
}
返回u.ull+0x80000000000000;
}
无符号长ULP_差异(双x,双y){
无符号长ullx=ULP(x);
无符号长ully=ULP(y);
如果(x>y)返回ullx-ully;
返回ully-ullx;
}
Michi,您已经知道了标准,那么您在标准中发现了什么,使浮点数的状态比较不是单光子的?或者你是如何得出结论的?请注意,相等的比较也是精确的。就是那个修圆工
$ ./a.exe
OK a:3.140000, b:3.140000
BAD a:103.140000, b:103.140000
eps = 0.00000000001
if( abs( x - y ) < eps ) {
printf("EQUAL!");
}
if (a==b) {
double ai = 1.0/a;
double bi = 1.0/b;
printf("%d\n", ai == bi);
} else {
printf("%d\n", 1);
}
// not highly portable
#include <assert.h>
unsigned long long ULP(double x) {
union {
double d;
unsigned long long ull;
} u;
assert(sizeof(double) == sizeof(unsigned long long));
u.d = x;
if (u.ull & 0x8000000000000000) {
u.ull ^= 0x8000000000000000;
return 0x8000000000000000 - u.ull;
}
return u.ull + 0x8000000000000000;
}
unsigned long long ULP_diff(double x, double y) {
unsigned long ullx = ULP(x);
unsigned long ully = ULP(y);
if (x > y) return ullx - ully;
return ully - ullx;
}