Binary Constants: FOLLOWUP
Jfriedl
jfriedl at frf.omron.co.jp
Sat Nov 25 19:14:35 AEST 1989
Two weeks ago I posted a question about how to effect binary
constants, as in the fictitious:
case 0b110011: /* "bsr.n" opcode */
I had a macro that allowed
case B(110011): /* "bsr.n" opcode */
The macro,
#define B(N) ( \
((1==(((2 ## N) )%10)) ) | \
((1==(((2 ## N)/10 )%10))<<1) | \
((1==(((2 ## N)/100 )%10))<<2) | \
((1==(((2 ## N)/1000 )%10))<<3) | \
((1==(((2 ## N)/10000 )%10))<<4) | \
((1==(((2 ## N)/100000 )%10))<<5) | \
((1==(((2 ## N)/1000000 )%10))<<6) | \
((1==(((2 ## N)/10000000)%10))<<7) )
allows binary constants up to 8 digits long, but looks horrible.
>From the non-net responses:
A number of people suggested that a preprocessor
could be easily written. [easy enough, but I'd rather not
have to do this].
However, one response, reprinted here (without permission --
hope it's ok), from uunet!peregrine.COM!dmi (Dean Inada) :
> Hah!
> Inspired, I find:
>
> #define D(N) (2 ## N)
> #define DTOB(N) ((N)%8 + (N)/125%64 + ((N)/15625%512&0700))
> #define B(N) DTOB(D(N))
>
> Encouraged, I go on;
>
> #define H(N) (0x ## N)
> #define HTOB(N) (\
> ((\
> ((\
> ((\
> (N)\
> *0x15)&0x21221881)%0xffff%0x1ff\
> *0x1001)&0x9216d)%0x1ff\
> *0x201)&c200ff)%0x7ff\
> )/*note: evaluates arg only once*/
>
> #define B(N) HTOB(H(N))
>
> Whew, I think I'll let someone else simplify this, and/or work on OtoB.
Inspired, I'd say. Having absolutely NO clue to the above, I asked for
the derivation (which, as it turns out, I didn't understand either).
It's somewhat long, but if you want it, let me know and I'll pass it
along.
Anyway, it did give me the idea to come up with:
#ifdef __STDC__
# define _FORCE_OCTAL(num) 0##num##U
#else
# define _FORCE_OCTAL(num) (0/**/num) /* well, it's worth a try */
#endif
#define _CONV_O2B_(N) \
((N & 000000000001U) \
|(N & 000000000010U)>>002 \
|(N & 000000000100U)>>004 \
|(N & 000000001000U)>>006 \
|(N & 000000010000U)>>010 \
|(N & 000000100000U)>>012 \
|(N & 000001000000U)>>014 \
|(N & 000010000000U)>>016 \
|(N & 000100000000U)>>020 \
|(N & 001000000000U)>>022 \
|(N & 010000000000U)>>024)
#define B(Num) _CONV_O2B_(_FORCE_OCTAL(Num))
which has the benefit of allowing up to 11 bits.
It's really much more natural than converting from decimal --
thanks Dean, for forging the path. I still wish, though,
that I could understand your derivation!
This new macro, above, would be much more compact if C had an operator
which meant "fold bits, keeping every third bit". Mmmm, maybe
if we sue..... (-:
On the net, there were a lot of people wishing that XJ311
had allowed stuff like 0b[01]+, but, apparently (from an
apparent XJ311 member), it would have been just "nice" to have.
Like it's also "nice" to have "for", "while", etc, rather than
having to use "goto", eh? Maybe not so dramatic but
0b[01]+ {yylval.i = atob(yytext+2); return INTEGER;}
is pretty not-so-dramatic too. Sheesh.
Oh, and one more response.
It was pointed out that I misspelled "wretched".
*jeff*
NB:
I'm going to be in The States for the next month on business.
[It'll be *GREAT* to have a cup of coffee for less than $3!]
Mail will follow me, but news won't, so please mail comments and flames.
Heck, I get so little mail, "yes | mail jeff" would even be appreciated.
Well, maybe not, but you get the idea..... (-:
-----------------------------------------------------------------------------
Jeffrey Eric Francis Friedl jfriedl at nff.ncl.omron
Omron Tateisi Electronics, Dept. OE Nagaokakyo, Japan
Fax: 011-81-75-955-2442 Phone: 011-81-75-951-5111 x154
direct path from UUNET: ...!uunet!othello!jfriedl
More information about the Comp.lang.c
mailing list