Failed to correctly compare two doubles simply with `==` in `EXPECT_EQ_DOUBLE`.
In test.c, we compare the equality of two doubles simply with ==:
#define EXPECT_EQ_DOUBLE(expect, actual) EXPECT_EQ_BASE((expect) == (actual), expect, actual, "%.17g")
I don't know whether it works fine for others, but it just won't work on my computer. (Windows 10, 64, with (MinGW.org GCC-8.2.0-3) 8.2.0)
To figure out what's wrong, I did a simple test with a seperate C file:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
if(3.1416 != strtod("3.1416", NULL)){
printf("NOT EQUAL!\n");
}else{
printf("EQUAL.\n");
}
return 0;
}
The interesting thing happens: the output of this program depends on the C standard I use to compile it.
If I compile it with gcc -std=c89 gcc -std=c99 gcc -std=c11 or gcc -std=c17, the output of running the executable will be NOT EQUAL!.
If I compile it with gcc(no standard specified and therefore using -std=gnu11), the output is EQUAL.
I don't know why this happens, but I think we'd better write EXPECT_EQ_DOUBLE in a more universal way despite the difference between OS and gcc version.
I found a feasible workaround:
#define EXPECT_EQ_DOUBLE(expect, actual) EXPECT_EQ_BASE((double)(expect) == (actual), expect, actual, "%.17g")
By explictly converting expect to double, this issue gets solved.
But I still have no idea about why this issue happens and why I can fix it in such a way.
Because of floating point error, the compare of equality of floating point numbers is unreliable.
Because of floating point error, the compare of equality of floating point numbers is unreliable.
@Syopain True, but see these issues: #29 #69
@keithnull strtod的实现应该是逐位计算的,所以计算过程中可能会有误差,我觉得这里应该用fabs(expect - actual) < (EPS) 来比较
@keithnull strtod的实现应该是逐位计算的,所以计算过程中可能会有误差,我觉得这里应该用
fabs(expect - actual) < (EPS)来比较
@Syopain You are right. But how to explain that (double)3.14156 == strtod("3.14156") works while 3.14156 == strtod("3.14156") not? I don't think this is due to the rounding error or strtod.
@keithnull strtod的实现应该是逐位计算的,所以计算过程中可能会有误差,我觉得这里应该用
fabs(expect - actual) < (EPS)来比较@Syopain You are right. But how to explain that
(double)3.14156 == strtod("3.14156")works while3.14156 == strtod("3.14156")not? I don't think this is due to the rounding error orstrtod.
I think it may depend on the environment.