[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 (Comment added) made by andygoth
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: Andy Goth (andygoth)
Date: 2007-01-20 23: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