F
Frederick Gotham
I'm trying to write extremely efficient, fully portable algorithms to
determine if an integer is odd or even. The most basic algorithms would be:
#define IS_ODD(x) ((x) % 2)
#define IS_EVEN(x) (!((x) % 2))
Attempting to make them slightly more efficient, we could change them to:
#define IS_ODD(x) ((x) & 1)
#define IS_EVEN(x) (!((x) & 1))
(Yes, some compilers may actually compile the former into the latter, but
we're playing the efficiency game here.)
Only thing though:-
The latter two will malfunction on One's Complement systems when
dealing with negative numbers. Thus, I have the following code... I'd
appreciate any comments or suggestions. No changes are required for Sign-
magnitude or for Two's Complement, but we must improvise for One's
Complement. Here we go:
#define SIGNMAG 0
#define ONES 1
#define TWOS 2
#if -1 & 3 == 1
#define NUMSYS SIGNMAG
#elif -1 & 3 == 2
#define NUMSYS ONES
#else
#define NUMSYS TWOS
#endif
#if NUMSYS != ONES
#define IS_ODD(x) ((x) & 1)
#define IS_EVEN(x) (!((x) & 1))
#else
#define ONE_IF_NEGATIVE(x) ((x) < 0)
#define IS_ODD(x) ( !((x) & 1) == ONE_IF_NEGATIVE((x)) )
#define IS_EVEN(x) ( !((x) & 1) != ONE_IF_NEGATIVE((x)) )
#endif
Unfortunately though, the One's Complement version evaluates the argument
twice.
Yes, I realise that the smart thing would probably just be to write "x %
2" and forget about it, but this is more for kicks than anything else.
determine if an integer is odd or even. The most basic algorithms would be:
#define IS_ODD(x) ((x) % 2)
#define IS_EVEN(x) (!((x) % 2))
Attempting to make them slightly more efficient, we could change them to:
#define IS_ODD(x) ((x) & 1)
#define IS_EVEN(x) (!((x) & 1))
(Yes, some compilers may actually compile the former into the latter, but
we're playing the efficiency game here.)
Only thing though:-
The latter two will malfunction on One's Complement systems when
dealing with negative numbers. Thus, I have the following code... I'd
appreciate any comments or suggestions. No changes are required for Sign-
magnitude or for Two's Complement, but we must improvise for One's
Complement. Here we go:
#define SIGNMAG 0
#define ONES 1
#define TWOS 2
#if -1 & 3 == 1
#define NUMSYS SIGNMAG
#elif -1 & 3 == 2
#define NUMSYS ONES
#else
#define NUMSYS TWOS
#endif
#if NUMSYS != ONES
#define IS_ODD(x) ((x) & 1)
#define IS_EVEN(x) (!((x) & 1))
#else
#define ONE_IF_NEGATIVE(x) ((x) < 0)
#define IS_ODD(x) ( !((x) & 1) == ONE_IF_NEGATIVE((x)) )
#define IS_EVEN(x) ( !((x) & 1) != ONE_IF_NEGATIVE((x)) )
#endif
Unfortunately though, the One's Complement version evaluates the argument
twice.
Yes, I realise that the smart thing would probably just be to write "x %
2" and forget about it, but this is more for kicks than anything else.