Autor
| C question
|
ARTRAG msx master Mensajes: 1802 | Publicado: Septiembre 14 2006, 23:08   |
I am programming a set of macros able to recognize if a char is in a given range.
The macro is supposed to be used with unsignad chars and returns a boolean
My question: is this set of macros
#define is_range1(x) (x < 4)
#define is_range2(x) ((x < 8) && (x >= 4))
#define is_range3(x) ((x < 16) && (x >= 8))
#define is_range4(x) ((x < 32) && (x >= 16))
#define is_range5(x) ((x < 64) && (x >= 32))
#define is_range6(x) ((x < 128) && (x >= 64))
#define is_range7(x) (x > 127)
equivalent to this other set of macros
#define is_range1(x) (x < 4)
#define is_range2(x) ((x & 4) == 4)
#define is_range3(x) ((x & 8) == 8)
#define is_range4(x) ((x & 16) == 16)
#define is_range5(x) ((x & 32) == 32)
#define is_range6(x) ((x & 64) == 64)
#define is_range7(x) (x > 127)
? And, if not why ?
IMHO the should be completely equivalent.
Actually they are not as the results of the C program
with the second set is completely wrong !!
     |
|
[D-Tail]
 msx guru Mensajes: 3026 | Publicado: Septiembre 15 2006, 00:06   |
Let's say, X=96, or $01100000.
Then, your first setup will work: is_range5(x) will return false, because 96 isn't in the domain. is_range6(x) will return true, because 96 is in the domain.
Your second setup will fail: is_range5(x) will return true, as $01100000 AND $00100000 == $00100000. Also, is_range6(x) will return true, as $01100000 AND $01000000 == $01000000.
Those is_range(y)(x) blocks are not equivalent. Only equivalents are is_range1(x) and is_range7(x).
|
|
dvik msx master Mensajes: 1376 | Publicado: Septiembre 15 2006, 00:17   |
This test is equivalent with the first one, but I'm not sure if it saves you anything:
#define is_range1(x) (x < 4)
#define is_range2(x) ((x & ~3) == 4)
#define is_range3(x) ((x & ~7) == 8)
#define is_range4(x) ((x & ~15) == 16)
#define is_range5(x) ((x & ~31) == 32)
#define is_range6(x) ((x & ~63) == 64)
#define is_range7(x) (x > 127)
Note that the compiler will calculate the ~'ed values for you so its not done runtime.
|
|
ARTRAG msx master Mensajes: 1802 | Publicado: Septiembre 15 2006, 00:44   |
I see my error!
thanks
it woks!
PS
in my program, the second method saves about 100 LM instructions
|
|
arnold_m msx lover Mensajes: 86 | Publicado: Septiembre 15 2006, 20:33   |
It is good practice to protect the arguments of macros with parentheses.
#define is_range4(x) ((x & ~15) == 16)
will not give the right results for is_range4(z+3) because it gets replaced with ((z+3 & ~15) == 16), which will be simplified by the compiler too ((z+3) == 16).
The proper way to define the macros is like this:
#define is_range4(x) (((x) & ~15) == 16)
Macros look just like functions in your code, but they are substitutions in the text handled by the preprocessor.
|
|
ARTRAG msx master Mensajes: 1802 | Publicado: Septiembre 15 2006, 23:18   |
thnx
|
|
|
|
|