Path: utzoo!attcan!uunet!kddlab!ccut!choshi!frf!jfriedl From: jfriedl@frf.omron.co.jp (Jfriedl) Newsgroups: comp.lang.c Subject: binary constants (??) Keywords: macro, constant, binary Message-ID: <305@frf.omron.co.jp> Date: 17 Nov 89 08:27:44 GMT Organization: OMRON TATEISI ELECTRONICS Co., Kyoto, Japan. Lines: 81 There's one (particular) hassle I've always had when programming in C and I thought I'd ask about it..... In some cases, I find it would be much more natural to represent integral constants in binary, but I don't know of an easy way to do this. For example, I find the mythical: (can you pretend these are binary constants? Sure, I knew you could): #define FLAG_A 00000001000 #define FLAG_B 00000010000 #define FLAG_C 00000100000 #define FLAG_D 00001000000 #define FLAG_E 00010000000 #define FLAG_F 00100000000 #define FLAG_MASK 00111111000 rather more immediately obvious than #define FLAG_A 0x0008 #define FLAG_B 0x0010 #define FLAG_C 0x0020 #define FLAG_D 0x0040 #define FLAG_E 0x0080 #define FLAG_F 0x0100 #define FLAG_MASK 0x01F8 This example may be contrived, but the idea is there. Not only does it indicate the desired value, but also that this data is inherently binary and, if applicable to the situation, the "width" of the data. So, I have this retched macro that seems to work for short binary constants: #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) ) (non-ANSI compilers might try "/**/" rather than " ## "). This has worked well for an 88K disassembler that I wrote, where I dealt a lot in instruction opcode fields, etc. For example, the following is pulled verbatim from it: . . . IMM16 = extract(16, bits of, inst, starting at bit, 0), S1 = extract( 5, bits of, inst, starting at bit, 16), D = extract( 5, bits of, inst, starting at bit, 21), which = extract( 6, bits of, inst, starting at bit, 26); /* first, just get the name of this instruction */ switch((int)which) { default: return(-1); case B(000000): name = "xmem.bu"; break; case B(000001): name = "xmem"; break; case B(000010): name = "ld.hu"; break; . . . To anyone familiar with the mc88100, and looking at the appropriate spot in the manual (as indicated nearby in the program), this is *wonderfully* clear. ANYWAY, finally to my questions: Is there a way better than the above macro to do this? I've gcc v1.36 -- does it have any special stuff for this? Any comments (other than "Ack!Gag!Barf!") about the above macro? I'll summarize if there seems to be enough interest... *jeff* ----------------------------------------------------------------------------- Jeffrey Eric Francis Friedl jfriedl@nff.ncl.omron.co.junet 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