jfriedl@frf.omron.co.jp (Jfriedl) (11/25/89)
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@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
dmi@peregrine.peregrine.com (Dean Inada) (11/26/89)
In article <308@frf.omron.co.jp> jfriedl@frf.omron.co.jp (Jfriedl) writes: >Two weeks ago I posted a question about how to effect binary >constants, as in the fictitious: > case 0b110011: /* "bsr.n" opcode */ ... > However, one response, reprinted here (without permission -- >hope it's ok), from uunet!peregrine.COM!dmi (Dean Inada) : >> #define DTOB(N) ((N)%8 + (N)/125%64 + ((N)/15625%512&0700)) ^^^^ Note that the %512 is superfluous here. Or, #define DTOB(N) ((N)*9/5%16 + ((N)*9/3125&0xf0)) Can anyone reduce this to one eval of (N)? >> #define H(N) (0x ## N) >> #define HTOB(N) (\ >> ((\ >> ((\ >> ((\ >> (N)\ >> *0x15)&0x21221881)%0xffff%0x1ff\ >> *0x1001)&0x9216d)%0x1ff\ >> *0x201)&c200ff)%0x7ff\ >> )/*note: evaluates arg only once*/ > >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). You might try tracing the intermediate values for 0x1, 0x10, 0x100, ... ,0x10000000 >It's somewhat long, but if you want it, let me know and I'll pass it >along. If you do pass it along, let me know where. >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..... (-: Picking up the gauntlet: -) #define _CONV_O2B(N) (\ (((((\ (N)%01777 /* 100001 */\ *04000001&050001545)%03777 /* 100011 */\ *04000001&010420001443)%07777 /* 100111 */\ *010001&030000547)%0777 /* 111111 */\ *02001&0200477)%0777 /* 10111111 */\ *0401&0200277)%01777 /* 11111111 */\ ) Only 8 bits worth, and no effort to optimize like the hex version, but that didn't get very far anyway. Anyone else care to try?