CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 17
  1. #1
    Join Date
    Jul 2007
    Posts
    609

    math logic confusion

    This should be simple, but I can't seem to figure out a logic behind this without hard coding tons of nested ifs, there's got to be a simple way.

    Say I got a class with these members:

    long int m_seconds;
    long int m_minutes;
    long int m_hours;
    long int m_days;


    I have two instances of this class, and I want to check if one of them is bigger then the other based on those values treated as time. I started coding it and got into a huge mess of if nests several levels deep. There must be a simpler way right?
    http://www.uovalor.com :: Free UO Server

  2. #2
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: math logic confusion

    Well, if you wanted to use no if statements at all you could go with something like:
    Code:
    bool operator<(const DateTime& lhs, const DateTime& rhs)
    {
        return lhs.m_days < rhs.m_days
            || (lhs.m_days == rhs.m_days
            && (lhs.m_hours < rhs.m_hours
            || (lhs.m_hours == rhs.m_hours
            && (lhs.m_minutes < rhs.m_minutes
            || (lhs.m_minutes == rhs.m_minutes
            && lhs.m_seconds < rhs.m_seconds)))));
    }
    But I am not sure if this would be obfuscation or clarification: on one hand, the pattern should be easy to discern, but on the other hand, you have quite a few nested parentheses that the structure does not clearly show.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  3. #3
    Join Date
    Jul 2007
    Posts
    609

    Re: math logic confusion

    Ah ok I was on right track, is there any speed difference or does compiler optimize it anyway?

    This is what I have:

    Code:
    	bool TimeSpan::operator>(const TimeSpan &other) const
    	{
    		if(m_days>other.m_days)return true;
    		else if(m_days<other.m_days)return false;
    		
    		//at this point days are equal
    		
    		if(m_hours>other.m_hours)return true;
    		else if(m_hours<other.m_hours)return false;
    		
    		//at this point hours are equal
    
    		if(m_minutes>other.m_minutes)return true;
    		else if(m_minutes<other.m_minutes)return false;
    		
    		//at this point hours are equal
    		
    		if(m_seconds>other.m_seconds)return true;
    		else if(m_seconds<other.m_seconds)return false;	
    		
    		//at this point seconds are equal, we return false since we want > and not =>
    
    		return false;	
    	}
    My >= operator checks against == followed by => so I'm not repeating code.
    http://www.uovalor.com :: Free UO Server

  4. #4
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: math logic confusion

    Quote Originally Posted by Red Squirrel
    Ah ok I was on right track, is there any speed difference or does compiler optimize it anyway?
    I doubt that it would make a difference either way once compiler does its optimisation. If this is a bottleneck you could always measure and see if one is faster than the other.

    Quote Originally Posted by Red Squirrel
    My >= operator checks against == followed by => so I'm not repeating code.
    It is more canonical to implement operator< instead of operator> since operator< is the one used by the standard generic algorithms by default. You do not actually need to use operator== to implement operator<= or operator>=. The trick is that with operator<, (a > b) == (b < a), (a <= b) == !(b < a), (a >= b) == !(a < b).

    In fact, by defining operator== and operator<, you can just #include <utility> and then do a using namespace std::rel_ops to get the other four (including operator!=).
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  5. #5
    Join Date
    Apr 1999
    Posts
    27,449

    Re: math logic confusion

    Quote Originally Posted by Red Squirrel View Post
    Ah ok I was on right track,
    I agree with laserlight -- overload operator < and operator == first, then write the other operators in terms of these operators. Writing a full-blown operator > seems to be a mistake (it would be where I work)-- you should spend the time writing operator < and operator ==. The other operators can then be written (using either laserlight's recommendation or with simple one-line functions) once < and == are implemented

    The < and == operators are used throughout the C++ algorithms (i.e. the term strict weak ordering is used in the definition of many algorithms, meaning operator <.)

    Regards,

    Paul McKenzie

  6. #6
    Join Date
    Apr 2007
    Location
    Mars NASA Station
    Posts
    1,436

    Re: math logic confusion

    Code:
    (a <= b) == !(b < a), (a >= b) == !(a < b).
    Great explanation.
    Thanks for your help.

  7. #7
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,635

    Re: math logic confusion

    Another approach would be to convert each to the total number of seconds and just compare the two numbers. That would be logically simpler.

  8. #8
    Join Date
    Oct 2008
    Posts
    1,456

    Re: math logic confusion

    Quote Originally Posted by Paul McKenzie View Post
    the term strict weak ordering is used in the definition of many algorithms, meaning operator <
    ok, but in that case the operator < must satisfy strict weak ordering axioms. Suppose you want to define, say, a simple partial order; in your opinion, what's the best practice ? defining only the operator <= or defining a (non-)member function ?

  9. #9
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: math logic confusion

    The rule of thumb is that you shouldn't use an operator in a way inconsistent with how the integers would use it. So for any "unusual" relations, use a named function.

    Besides, for a partial ordering you need three results: true, false, and unrelated. You can't get that with any of the existing operators, I think. Best you could do would be to make "unrelated" mean "false".
    Last edited by Lindley; December 17th, 2008 at 08:58 AM.

  10. #10
    Join Date
    Oct 2008
    Posts
    1,456

    Re: math logic confusion

    Quote Originally Posted by Lindley
    Besides, for a partial ordering you need three results: true, false, and unrelated
    well, in mathematical terms if R is a relation then aRb <=> (a,b) belongs to R , so what you call "unrelated" is "false" (but I understand what you mean ...).

    anyway, thanks for The rule of thumb

  11. #11
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: math logic confusion

    Another method could be...
    Code:
    return (lhs.m_days < rhs.m_days) ? true :
               ((lhs.m_hours < rhs.m_hours) ? true :
                   ((lhs.m_minutes < rhs.m_minutes) ? true :
                       (lhs.m_seconds < rhs.m_seconds)));
    though it wouldn't score high on readability.
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

  12. #12
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,635

    Re: math logic confusion

    I'll try this again.

    Give the class a method, call it say GetTotalSeconds();
    Code:
    int MyClass::GetTotalSeconds()
    {
        return m_Seconds + (m_Minutes * 60) + (m_Hours * 60 * 60) + (m_Days * 60 * 60 * 24);
    }
    Then just compare two initialized objects.
    Code:
    if(object1.GetTotalSeconds() < object2.GetTotalSeconds())

  13. #13
    Join Date
    Mar 2002
    Location
    St. Petersburg, Florida, USA
    Posts
    12,125

    Re: math logic confusion

    Quote Originally Posted by GCDEF View Post
    I'll try this again.

    Give the class a method, call it say GetTotalSeconds();
    Total Seconds can be useful for other purposes..but it the ONLY reason is for a compare. You can make this much simpler and smaller/faster

    Code:
    long value = m_Days << 18 | m_Hours < 12 | m_Minutes << 6 | m_Seconds;
    This will calcuate a "funny number" that is monotonic (and thus can be compared)
    TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
    2008, 2009,2010
    In theory, there is no difference between theory and practice; in practice there is.

    * Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
    * How NOT to post a question here
    * Of course you read this carefully before you posted
    * Need homework help? Read this first

  14. #14
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: math logic confusion

    Quote Originally Posted by GCDEF
    Give the class a method, call it say GetTotalSeconds();
    Yes, and then operator< can be a non-member non-friend (though GetTotalSeconds() should be const-correct; it is not const-correct in the example).
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  15. #15
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,635

    Re: math logic confusion

    Quote Originally Posted by TheCPUWizard View Post
    Total Seconds can be useful for other purposes..but it the ONLY reason is for a compare. You can make this much simpler and smaller/faster

    Code:
    long value = m_Days << 18 | m_Hours < 12 | m_Minutes << 6 | m_Seconds;
    This will calcuate a "funny number" that is monotonic (and thus can be compared)
    I'll take your word for it with that one.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured