[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 17:22
Message generated for change (Comment added) made by konforce
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: Closed
>Resolution: Fixed
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: Matthew Leverton (konforce)
Date: 2007-08-09 16:19

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

On the 4.3/4.9 branches, MID has been changed to work with all cases.
CLAMP has been introduced to mimic the old behavior. 

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

Comment By: Peter Wang (tjaden)
Date: 2007-01-20 17: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-20 17:37

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

File Added: mid.c

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

Comment By: Andy Goth (andygoth)
Date: 2007-01-20 17: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/