[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-21 10:22
Message generated for change (Comment added) made by tjaden
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.

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

>Comment By: Peter Wang (tjaden)
Date: 2007-01-21 10:53

Message:
Logged In: YES 
user_id=28616
Originator: NO

Yes, this is a known problem.  It's not really a bug---the macro does what
it's supposed to and the Allegro source always uses it correctly---but it
is misnamed and causes confusion.  MID() is undocumented so users
shouldn't actually depend on it, but I'm afraid many people *do*.  We can
compromise by fixing MID(), and introduce CLAMP() for the old behaviour
(if necessary).  But even then, I'd recommend not depending on the fixed
behaviour so your programs don't fail subtly if compiled with an older
version of Allegro.


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

Comment By: Andy Goth (andygoth)
Date: 2007-01-21 10:37

Message:
Logged In: YES 
user_id=8653
Originator: YES

File Added: mid.c

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

Comment By: Andy Goth (andygoth)
Date: 2007-01-21 10:35

Message:
Logged In: YES 
user_id=8653
Originator: YES

Gag, SF didn't preserve the formatting, so I'm posting an attachment which
hopefully will show up nicer.
File Added: mid.c

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

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/