0

I have two vectors:

std::vector<double> calculatedValues = calculateValues();
std::vector<double> expectedValues = {1.1, 1.2};

I am using cpputest to verify if these vectors are equal:

CHECK_TRUE(calculatedValues == expectedValues)

This is working. However, I am wondering whether I shouldn't use some tolerance, because after all I am comparing doubles.

Mat
  • 202,337
  • 40
  • 393
  • 406
Pietair
  • 396
  • 2
  • 8
  • 18
  • 8
    I don't think we'll be able to answer this for you without knowing what the requirements of your program are. – ApproachingDarknessFish Feb 08 '16 at 10:25
  • 2
    This question doesn't really seem to be about `vector`; that seems incidental. It's more about floating point, epsilon, etc. - all the usual suspects, discussed in depth in many other threads. ;-) Once you've decided on your chosen method/tolerance, you should be able to provide a custom comparator function, or perhaps even overload (free or inline) `operator==` for your vector, and perform iterative comparison using your own comparator. – underscore_d Feb 08 '16 at 10:40
  • One cannot just throw in epsilon and expect to have a satisfactory solution - for some purposes exact equality is required (validating deterministic computing algorithms), for others equality to say three decimal places might be required (satnav for example, 1 metre is plenty for arriving at your destination in a car) to CAD/CAM where sensible notions of equality depend on the accuracy you desire/the machine is capable of. Bottom line: You need to think about the system you are modelling, and what counts as "equal" in that system, and translate that concept to your program. – Ben Feb 08 '16 at 17:18

3 Answers3

3

Instead of operator== you can use std::equal() with a custom epsilon:

bool equal = std::equal(calculatedValues.begin(), calculatedValues.end(), expectedValues.begin(),
                        [](double value1, double value2)
                        {
                            constexpr double epsilon = 0.01; // Choose whatever you need here
                            return std::fabs(value1 - value2) < epsilon;
                        });
CHECK_TRUE(equal);
ollo
  • 24,797
  • 14
  • 106
  • 155
2

To compare floating point values you should do something like this:

bool is_equal(double a, double b) {

    return (abs(a-b)/b < 0.0001); // 0.00001 value can be a relative value
}

You can adapt it to compare your vectors.

Pierre
  • 1,162
  • 12
  • 29
1

Yes, you should use some tolerance because floating point operations are not guaranteed to yield the exact same results on different CPUs. There can be e.g. roundoff errors.

However, the SSE/SSE2 standards do provide reproducible floating point math, so you may consider using the compile flag /ARCH:SSE2 as an alternative. That said, it is difficult to ensure that no x87 math is used anywhere in the app, so be careful!

Sven Nilsson
  • 1,861
  • 10
  • 11