0

I am overloading operators > < == in a simple time class.

double exchange_time::seconds_from_midnight() const {
    return seconds + minutes * 60.0 + hours * 3600.0 + milliseconds / 1000.0;
}

bool exchange_time::operator<(const exchange_time& other) const
{
    return seconds_from_midnight() < other.seconds_from_midnight();
}

bool exchange_time::operator>(const exchange_time& other) const
{
    return seconds_from_midnight() > other.seconds_from_midnight();
}

bool exchange_time::operator==(const exchange_time& other) const
{
    return seconds_from_midnight() == other.seconds_from_midnight();
}

The > and < work perfect. However the == yields false and my test fails:

TEST_F(exchange_time_test, comparison) {
    exchange_time et1, et2;
    et1.set("93500001");
    et2.set("93500123");
    EXPECT_TRUE(et2 > et1);
    EXPECT_TRUE(et1 < et2);
    EXPECT_TRUE(et2 == et2);
}

Is there something I'm missing ?

Here's my declaration:

class exchange_time {
    public:
        void set(string timestamp);
        unsigned short int get_milliseconds() { return milliseconds; }
        unsigned short int get_seconds() { return seconds; }
        unsigned short int get_minutes() { return minutes; }
        unsigned short int get_hours() { return hours; }
        double seconds_from_midnight() const;
        bool operator<(const exchange_time& other) const;
        bool operator>(const exchange_time& other) const;
        bool operator==(const exchange_time& other) const;
    private:
        unsigned short int milliseconds;
        unsigned short int seconds;
        unsigned short int minutes;
        unsigned short int hours;
};
18
  • 5
    double seconds_from_midnight(); doubles are imprecise. One could be 1.000000000001 and another 0.9999999999999. More here: Is floating point math broken? Commented Mar 2, 2017 at 17:52
  • 1
    Possible duplicate of Is floating point math broken? Commented Mar 2, 2017 at 17:52
  • 1
    but that's literally the same number in this case Commented Mar 2, 2017 at 17:53
  • 1
    Note that all your functions and operators except of set should const. Commented Mar 2, 2017 at 17:54
  • 5
    How is the provided timestamp translated into hours, minutes, seconds, and milliseconds? How does the seconds_from_midnight function work? Please provide a minimal reproducible example Commented Mar 2, 2017 at 17:58

1 Answer 1

4

Never compare equality for double numbers. Check if they are almost equal. The most common way is to use an epsilon to compare the values.

bool exchange_time::operator==(exchange_time other)
{
  return abs(seconds_from_midnight() - other.seconds_from_midnight()) < EPS;
}

Where EPS is a very small value. If you need accurate comparison, you need to define your own Fraction class.

EDIT
EPS stands for Epsilon, which is defined as A very small, insignificant, or negligible quantity of something by Dictionary.com.

Sign up to request clarification or add additional context in comments.

2 Comments

Recommend expanding "eps" to the full word: "epsilon". This will make it much easier for a reader to seek more information with a web search.
@user4581301 Ok. I originally added EPS because it is so popular in competitive programming culture that almost everybody uses it almost everyday. I didn't know somebody may complain :D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.