I’m trying to compare two class objects, which has both been initialized with 0.0, but for some reason C++ decides to convert the 0.0 to some extremly small value instead of keeping the 0.0, which makes the comparison fail as the value it converts to is not always exactly the same.
Vector.cpp
#include "Vector.h"
// operator overloadings
bool Vector::operator==(const Vector &rhs) const
{
return x == rhs.x && y == rhs.y;
}
bool Vector::operator!=(const Vector &rhs) const
{
return x != rhs.x || y != rhs.y;
}
Vector.h
#pragma once
class Vector
{
private:
double x;
double y;
public:
// constructor
Vector(double x = 0.0, double y = 0.0){};
// operator overloading
bool operator==(const Vector &rhs) const;
bool operator!=(const Vector &rhs) const;
};
main.cpp
#include "Vector.h"
#include <cassert>
using namespace std;
int main()
{
Vector zero{};
// check default constructor
assert((Vector{0.0, 0.0} == zero));
What is going on here and how should it be rewritten?
I’m using the clang compiler if it makes any difference.
>Solution :
Your Vector class never initializes the x and y members.
Since the member variables are uninitialized, they will have an indeterminate value, which you should look at like it was random or garbage. Using indeterminate values of any kind in any way, leads to undefined behavior.
To initialize the member variables, use a constructor initializer list:
Vector(double x = 0.0, double y = 0.0)
: x{ x }, y{ y }
{
}
On another note, floating point arithmetic on a computer will lead to rounding errors. The more operations you perform, the larger the error will be. And sooner or later you will think that floating point math is broken.
All this rounding of course means that it’s almost impossible to do exact comparisons of floating point values.
The common way is to use an epsilon, a small margin of error, for your comparisons.