[AD] [ alleg-Bugs-1640516 ] MID() gives incorrect results

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


Bugs item #1640516, was opened at 2007-01-20 23:22
Message generated for change (Tracker Item Submitted) made by Item Submitter
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105665&aid=1640516&group_id=5665

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: Core Library
Group: 4.2.0rc2
Status: Open
Resolution: None
Priority: 5
Private: No
Submitted By: Andy Goth (andygoth)
Assigned to: Nobody/Anonymous (nobody)
Summary: MID() gives incorrect results

Initial Comment:
In file "include/allegro/base.h", the MID preprocessor macro is #defined to be "MAX((x), MIN((y), (z)))", which gives incorrect results whenever "x" is the largest of the three arguments.

 MID(1,2,3) -> MAX(1,MIN(2,3)) -> MAX(1,2) -> 2
 MID(1,3,2) -> MAX(1,MIN(3,2)) -> MAX(1,2) -> 2
 MID(2,1,3) -> MAX(2,MIN(1,3)) -> MAX(2,1) -> 2
 MID(2,3,1) -> MAX(2,MIN(3,1)) -> MAX(2,1) -> 2
 MID(3,1,2) -> MAX(3,MIN(1,2)) -> MAX(3,1) -> 3
 MID(3,2,1) -> MAX(3,MIN(2,1)) -> MAX(3,1) -> 3

This bug has been in Allegro for as long as I can remember, at least back to the 3.0 release.  And I'm just now getting around to reporting it. :^)

Here is a corrected version:

 #define MID(x,y,z) (\
      ((x) <= (y) && (y) <= (z)) ? (y)\
    : ((x) <= (z) && (z) <= (y)) ? (z)\
    : ((y) <= (x) && (x) <= (z)) ? (x)\
    : ((y) <= (z) && (z) <= (x)) ? (z)\
    : ((z) <= (x) && (x) <= (y)) ? (x)\
    :                              (y))

Here's a test procedure:

 int main(void)
 {
     int x, y, z;
     for (x = 1; x <= 3; ++x) {
         for (y = 1; y <= 3; ++y) {
             for (z = 1; z <= 3; ++z) {
                 printf("MID(%d,%d,%d) = %d    ",
                        x, y, z, MID(x, y, z));
             }
             printf("\n");
         }
     }
     return EXIT_SUCCESS;
 }

And this is its output:

 MID(1,1,1) = 1    MID(1,1,2) = 1    MID(1,1,3) = 1
 MID(1,2,1) = 1    MID(1,2,2) = 2    MID(1,2,3) = 2
 MID(1,3,1) = 1    MID(1,3,2) = 2    MID(1,3,3) = 3
 MID(2,1,1) = 1    MID(2,1,2) = 2    MID(2,1,3) = 2
 MID(2,2,1) = 2    MID(2,2,2) = 2    MID(2,2,3) = 2
 MID(2,3,1) = 2    MID(2,3,2) = 2    MID(2,3,3) = 3
 MID(3,1,1) = 1    MID(3,1,2) = 2    MID(3,1,3) = 3
 MID(3,2,1) = 2    MID(3,2,2) = 2    MID(3,2,3) = 3
 MID(3,3,1) = 3    MID(3,3,2) = 3    MID(3,3,3) = 3

Since MID() is most useful for clamping a number between minimum and maximum values, its most obvious usage is MID(min, val, max) with min < max.  This is probably why this problem has gone undetected until now.

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105665&aid=1640516&group_id=5665




Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/