473,424 Members | 1,844 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,424 software developers and data experts.

How to convert binary to hex using a macro?

Hi there:
These days I came to a problem that I failed to convert a binary
number to a hex number using a macro. For example:

int a = BINARY4(0101) will become int a = 0x5;
int a = BINARY8(0001,0101) will become int a = 0x15;
...etc.

I've written the following macros:

#define HEX_0000 0
#define HEX_0101 5
... ...
#define HEX_(a) HEX_ ## a
#define COMBINE(a) (0x ## a)
#define BINARY(a) COMBINE(HEX_(a))

These macros work all right in VC7, but when I compile the program
using VC8 or GCC-3.4.4, the result is wrong. When using GCC, the result
is:

int a = BINARY4(0101) --> int a = (0xHEX_(0101)); // COMBINE() is
explained first;

It seems that the order of macro explanation is different in VC7
and GCC.
Well, which one is right? Does standard C support recursive macro
explanation (just like what VC7 does)?
If I want to write such a convert macro which can be compiled by
VC7 and GCC, how should I do?
Thanks a lot!

Feb 24 '06 #1
9 7608
Chen Shu wrote:
These days I came to a problem that I failed to convert a binary
number to a hex number using a macro.


Perhaps you'll want to consider this contribution:
http://groups.google.com/group/comp....430b6d3da12c8f

To the C police: Is any UB involved?
Feb 24 '06 #2
On 2006-02-24, Chen Shu <yi******@gmail.com> wrote:
Hi there:
These days I came to a problem that I failed to convert a binary
number to a hex number using a macro. For example:

int a = BINARY4(0101) will become int a = 0x5;
int a = BINARY8(0001,0101) will become int a = 0x15;
...etc.

I've written the following macros:

#define HEX_0000 0
#define HEX_0101 5
... ...
#define HEX_(a) HEX_ ## a
#define COMBINE(a) (0x ## a)
#define BINARY(a) COMBINE(HEX_(a))

These macros work all right in VC7, but when I compile the program
using VC8 or GCC-3.4.4, the result is wrong. When using GCC, the result
is:

int a = BINARY4(0101) --> int a = (0xHEX_(0101)); // COMBINE() is
explained first;

It seems that the order of macro explanation is different in VC7
and GCC.
Well, which one is right? Does standard C support recursive macro
explanation (just like what VC7 does)?
If I want to write such a convert macro which can be compiled by
VC7 and GCC, how should I do?
Thanks a lot!


Certain things involving the token-pasting operator are
implementation-defined. Try wrapping it in more macros to be able to
make the precedence explicit. An extra level of indirection also seems
to help [i've also seen it help with the stringize operator]

This seems to work - Only tested with gcc, but it's probably hard to
screw up.

#define PASTE(a,b)a##b
#define PASTE2(a,b)PASTE(a,b)
#define x(y)y
#define HEX_(x)PASTE(HEX_,x)
#define Ox(x)PASTE(0x,x)
#define HEX_0100 4
#define HEX_0010 2
#define HEX(x)
#define BINARY4(x)Ox(HEX_(x))
#define BINARY8(x,y)PASTE2(BINARY4(x),HEX_(y))
BINARY4(0100)
BINARY8(0100,0010)
Feb 24 '06 #3
Jordan Abel <ra*******@gmail.com> writes:
On 2006-02-24, Chen Shu <yi******@gmail.com> wrote:
Hi there:
These days I came to a problem that I failed to convert a binary
number to a hex number using a macro. For example:

int a = BINARY4(0101) will become int a = 0x5;
int a = BINARY8(0001,0101) will become int a = 0x15;
...etc.

I've written the following macros:

#define HEX_0000 0
#define HEX_0101 5
... ...
#define HEX_(a) HEX_ ## a
#define COMBINE(a) (0x ## a)
#define BINARY(a) COMBINE(HEX_(a))

<snip>
Certain things involving the token-pasting operator are
implementation-defined. Try wrapping it in more macros to be able to
make the precedence explicit. An extra level of indirection also seems
to help [i've also seen it help with the stringize operator]
More macros aren't necessary. The level of indirection is.
This seems to work - Only tested with gcc, but it's probably hard to
screw up.

#define PASTE(a,b)a##b
#define PASTE2(a,b)PASTE(a,b)
#define x(y)y
#define HEX_(x)PASTE(HEX_,x)
#define Ox(x)PASTE(0x,x)
#define HEX_0100 4
#define HEX_0010 2
#define HEX(x)
#define BINARY4(x)Ox(HEX_(x))
#define BINARY8(x,y)PASTE2(BINARY4(x),HEX_(y))
BINARY4(0100)
BINARY8(0100,0010)


Playing around until it works is not usually a good way to generate
portable code. In your case, it has. But note that the x() macro above
isn't actually used anywhere, so it could be eliminated. Also, you
could eliminate HEX_() and 0x() by simply using PASTE2() directly:
it's the indirection that forces the arguments to be recursively
expanded. When a parameter is encountered after a # or next to a ##,
it will /not/ be macro-replaced, which is why the original
COMBINE(HEX_(a)) /must/ produce 0xHEX_(a) (which, since it isn't
defined as a macro, won't be further replaced).

AIUI, this has never been implementation-defined behavior, and VC7 was
wrong to produce "correct" results.

-Micah
Feb 24 '06 #4
On 2006-02-24, Micah Cowan <mi***@cowan.name> wrote:
Jordan Abel <ra*******@gmail.com> writes:
On 2006-02-24, Chen Shu <yi******@gmail.com> wrote:
> Hi there:
> These days I came to a problem that I failed to convert a binary
> number to a hex number using a macro. For example:
>
> int a = BINARY4(0101) will become int a = 0x5;
> int a = BINARY8(0001,0101) will become int a = 0x15;
> ...etc.
>
> I've written the following macros:
>
> #define HEX_0000 0
> #define HEX_0101 5
> ... ...
> #define HEX_(a) HEX_ ## a
> #define COMBINE(a) (0x ## a)
> #define BINARY(a) COMBINE(HEX_(a))
>

<snip>
Certain things involving the token-pasting operator are
implementation-defined. Try wrapping it in more macros to be able to
make the precedence explicit. An extra level of indirection also seems
to help [i've also seen it help with the stringize operator]


More macros aren't necessary. The level of indirection is.
This seems to work - Only tested with gcc, but it's probably hard to
screw up.

#define PASTE(a,b)a##b
#define PASTE2(a,b)PASTE(a,b)
#define x(y)y
#define HEX_(x)PASTE(HEX_,x)
#define Ox(x)PASTE(0x,x)
#define HEX_0100 4
#define HEX_0010 2
#define HEX(x)
#define BINARY4(x)Ox(HEX_(x))
#define BINARY8(x,y)PASTE2(BINARY4(x),HEX_(y))
BINARY4(0100)
BINARY8(0100,0010)


Playing around until it works is not usually a good way to generate
portable code. In your case, it has. But note that the x() macro above
isn't actually used anywhere, so it could be eliminated. Also, you
could eliminate HEX_() and 0x() by simply using PASTE2() directly:
it's the indirection that forces the arguments to be recursively
expanded. When a parameter is encountered after a # or next to a ##,
it will /not/ be macro-replaced, which is why the original
COMBINE(HEX_(a)) /must/ produce 0xHEX_(a) (which, since it isn't
defined as a macro, won't be further replaced).


I tried to use HEX_ and Ox to provide the extra level of indirection -
any idea why it didn't work?

AIUI, this has never been implementation-defined behavior, and VC7 was
wrong to produce "correct" results.

-Micah

Feb 24 '06 #5
On 2006-02-24, Jordan Abel <ra*******@gmail.com> wrote:
On 2006-02-24, Micah Cowan <mi***@cowan.name> wrote:
Jordan Abel <ra*******@gmail.com> writes:
On 2006-02-24, Chen Shu <yi******@gmail.com> wrote:
> Hi there:
> These days I came to a problem that I failed to convert a binary
> number to a hex number using a macro. For example:
>
> int a = BINARY4(0101) will become int a = 0x5;
> int a = BINARY8(0001,0101) will become int a = 0x15;
> ...etc.
>
> I've written the following macros:
>
> #define HEX_0000 0
> #define HEX_0101 5
> ... ...
> #define HEX_(a) HEX_ ## a
> #define COMBINE(a) (0x ## a)
> #define BINARY(a) COMBINE(HEX_(a))
>


<snip>
Certain things involving the token-pasting operator are
implementation-defined. Try wrapping it in more macros to be able to
make the precedence explicit. An extra level of indirection also seems
to help [i've also seen it help with the stringize operator]


More macros aren't necessary. The level of indirection is.
This seems to work - Only tested with gcc, but it's probably hard to
screw up.

#define PASTE(a,b)a##b
#define PASTE2(a,b)PASTE(a,b)
#define x(y)y
#define HEX_(x)PASTE(HEX_,x)
#define Ox(x)PASTE(0x,x)
#define HEX_0100 4
#define HEX_0010 2
#define HEX(x)
#define BINARY4(x)Ox(HEX_(x))
#define BINARY8(x,y)PASTE2(BINARY4(x),HEX_(y))
BINARY4(0100)
BINARY8(0100,0010)


Playing around until it works is not usually a good way to generate
portable code. In your case, it has. But note that the x() macro above
isn't actually used anywhere, so it could be eliminated. Also, you
could eliminate HEX_() and 0x() by simply using PASTE2() directly:
it's the indirection that forces the arguments to be recursively
expanded. When a parameter is encountered after a # or next to a ##,
it will /not/ be macro-replaced, which is why the original
COMBINE(HEX_(a)) /must/ produce 0xHEX_(a) (which, since it isn't
defined as a macro, won't be further replaced).


I tried to use HEX_ and Ox to provide the extra level of indirection -
any idea why it didn't work?


Also, why doesn't

#define PASTE(a,b) a/**/b

make it provide correct results in K&R mode? It's not particularly
important, but I was curious.
Feb 24 '06 #6
Jordan Abel <ra*******@gmail.com> writes:
On 2006-02-24, Jordan Abel <ra*******@gmail.com> wrote:
On 2006-02-24, Micah Cowan <mi***@cowan.name> wrote:
Jordan Abel <ra*******@gmail.com> writes:

#define PASTE(a,b)a##b
#define PASTE2(a,b)PASTE(a,b)
#define x(y)y
#define HEX_(x)PASTE(HEX_,x)
#define Ox(x)PASTE(0x,x)
#define HEX_0100 4
#define HEX_0010 2
#define HEX(x)
#define BINARY4(x)Ox(HEX_(x))
#define BINARY8(x,y)PASTE2(BINARY4(x),HEX_(y))
BINARY4(0100)
BINARY8(0100,0010)

Playing around until it works is not usually a good way to generate
portable code. In your case, it has. But note that the x() macro above
isn't actually used anywhere, so it could be eliminated. Also, you
could eliminate HEX_() and 0x() by simply using PASTE2() directly:
it's the indirection that forces the arguments to be recursively
expanded. When a parameter is encountered after a # or next to a ##,
it will /not/ be macro-replaced, which is why the original
COMBINE(HEX_(a)) /must/ produce 0xHEX_(a) (which, since it isn't
defined as a macro, won't be further replaced).
I tried to use HEX_ and Ox to provide the extra level of indirection -
any idea why it didn't work?


I thought you said it /did/ work. It does for me, and looks fine, if
verbose. I just meant you don't need the HEX_() and 0x() macros
weren't necessary: PASTE2() provides adequate indirection.
Also, why doesn't

#define PASTE(a,b) a/**/b

make it provide correct results in K&R mode? It's not particularly
important, but I was curious.


As to that... the Standard requires that comments be treated as a
single space. AFAIK, in K&R days it probably was up to the
implementation to decide whether this would result in "token pasting"
or a single space. Someone with a good deal more experience in K&R C
should probably speak up now.
Feb 24 '06 #7
On 2006-02-24, Micah Cowan <mi***@cowan.name> wrote:
Jordan Abel <ra*******@gmail.com> writes:
On 2006-02-24, Jordan Abel <ra*******@gmail.com> wrote:
> On 2006-02-24, Micah Cowan <mi***@cowan.name> wrote:
>> Jordan Abel <ra*******@gmail.com> writes:
>>
>>> #define PASTE(a,b)a##b
>>> #define PASTE2(a,b)PASTE(a,b)
>>> #define x(y)y
>>> #define HEX_(x)PASTE(HEX_,x)
>>> #define Ox(x)PASTE(0x,x)
>>> #define HEX_0100 4
>>> #define HEX_0010 2
>>> #define HEX(x)
>>> #define BINARY4(x)Ox(HEX_(x))
>>> #define BINARY8(x,y)PASTE2(BINARY4(x),HEX_(y))
>>> BINARY4(0100)
>>> BINARY8(0100,0010)
>>
>> Playing around until it works is not usually a good way to generate
>> portable code. In your case, it has. But note that the x() macro above
>> isn't actually used anywhere, so it could be eliminated. Also, you
>> could eliminate HEX_() and 0x() by simply using PASTE2() directly:
>> it's the indirection that forces the arguments to be recursively
>> expanded. When a parameter is encountered after a # or next to a ##,
>> it will /not/ be macro-replaced, which is why the original
>> COMBINE(HEX_(a)) /must/ produce 0xHEX_(a) (which, since it isn't
>> defined as a macro, won't be further replaced).
>
> I tried to use HEX_ and Ox to provide the extra level of indirection -
> any idea why it didn't work?


I thought you said it /did/ work. It does for me, and looks fine, if
verbose. I just meant you don't need the HEX_() and 0x() macros
weren't necessary: PASTE2() provides adequate indirection.
Also, why doesn't

#define PASTE(a,b) a/**/b

make it provide correct results in K&R mode? It's not particularly
important, but I was curious.


As to that... the Standard requires that comments be treated as a
single space. AFAIK, in K&R days it probably was up to the
implementation to decide whether this would result in "token pasting"
or a single space. Someone with a good deal more experience in K&R C
should probably speak up now.


except it ends up 0x4 2 not 0x 4 2
Feb 24 '06 #8
On 2006-02-24, Micah Cowan <mi***@cowan.name> wrote:
Jordan Abel <ra*******@gmail.com> writes:
On 2006-02-24, Jordan Abel <ra*******@gmail.com> wrote:
> On 2006-02-24, Micah Cowan <mi***@cowan.name> wrote:
>> Jordan Abel <ra*******@gmail.com> writes:
>>
>>> #define PASTE(a,b)a##b
>>> #define PASTE2(a,b)PASTE(a,b)
>>> #define x(y)y
>>> #define HEX_(x)PASTE(HEX_,x)
>>> #define Ox(x)PASTE(0x,x)
>>> #define HEX_0100 4
>>> #define HEX_0010 2
>>> #define HEX(x)
>>> #define BINARY4(x)Ox(HEX_(x))
>>> #define BINARY8(x,y)PASTE2(BINARY4(x),HEX_(y))
>>> BINARY4(0100)
>>> BINARY8(0100,0010)
>>
>> Playing around until it works is not usually a good way to generate
>> portable code. In your case, it has. But note that the x() macro above
>> isn't actually used anywhere, so it could be eliminated. Also, you
>> could eliminate HEX_() and 0x() by simply using PASTE2() directly:
>> it's the indirection that forces the arguments to be recursively
>> expanded. When a parameter is encountered after a # or next to a ##,
>> it will /not/ be macro-replaced, which is why the original
>> COMBINE(HEX_(a)) /must/ produce 0xHEX_(a) (which, since it isn't
>> defined as a macro, won't be further replaced).
>
> I tried to use HEX_ and Ox to provide the extra level of indirection -
> any idea why it didn't work?

I thought you said it /did/ work. It does for me, and looks fine, if
verbose. I just meant you don't need the HEX_() and 0x() macros
weren't necessary: PASTE2() provides adequate indirection.


I was wondering why HEX_() and Ox() alone did not provide adequate
indirection. PASTE2 was added after those failed.
Also, why doesn't

#define PASTE(a,b) a/**/b

make it provide correct results in K&R mode? It's not particularly
important, but I was curious.


As to that... the Standard requires that comments be treated as a
single space. AFAIK, in K&R days it probably was up to the
implementation to decide whether this would result in "token pasting"
or a single space. Someone with a good deal more experience in K&R C
should probably speak up now.

Feb 25 '06 #9
Jordan Abel <ra*******@gmail.com> writes:
On 2006-02-24, Micah Cowan <mi***@cowan.name> wrote:
Jordan Abel <ra*******@gmail.com> writes:
On 2006-02-24, Jordan Abel <ra*******@gmail.com> wrote:
> On 2006-02-24, Micah Cowan <mi***@cowan.name> wrote:
>> Jordan Abel <ra*******@gmail.com> writes:
>>
>>> #define PASTE(a,b)a##b
>>> #define PASTE2(a,b)PASTE(a,b)
>>> #define x(y)y
>>> #define HEX_(x)PASTE(HEX_,x)
>>> #define Ox(x)PASTE(0x,x)
>>> #define HEX_0100 4
>>> #define HEX_0010 2
>>> #define HEX(x)
>>> #define BINARY4(x)Ox(HEX_(x))
>>> #define BINARY8(x,y)PASTE2(BINARY4(x),HEX_(y))
>>> BINARY4(0100)
>>> BINARY8(0100,0010)
<snip>
> I tried to use HEX_ and Ox to provide the extra level of indirection -
> any idea why it didn't work?


I thought you said it /did/ work. It does for me, and looks fine, if
verbose. I just meant you don't need the HEX_() and 0x() macros
weren't necessary: PASTE2() provides adequate indirection.


I was wondering why HEX_() and Ox() alone did not provide adequate
indirection. PASTE2 was added after those failed.


Well, your BINARY4() doesn't use PASTE2: only HEX_() and Ox() (BTW,
that's a /really/ misleading name...), and it works fine.

Now, trying

#define BINARY8(x,y) PASTE(BINARY4(x),HEX_(y))

wouldn't work, because the arguments won't be macro-expanded before
the pasting occurs. It will try to paste exactly (unexpanded):

BINARY4(x)

with

HEX_(y)

..

Since the ) token pasted against the HEX_ token
doesn't yield a single resulting token, so UB results (and, at least
on my system, an error).

Is that what you wanted to know?
Feb 25 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
by: dixie | last post by:
Can someone familiar with Access 2003 please answer this question? I am asking because I don't have the use of A2003. When Access 2003 finds an Access 2000 database, does it come up with some...
6
by: Tom Torfs | last post by:
Hello All, I've been missing the lack of support for binary numeric literals in C. To get around it I wrote the following handy macros, which allows you to simply write something like: ...
6
by: Kelvin | last post by:
Hi everyone: when we wanna use hex numbers in C, we usually write something like: int hex_num = 0x12F9; but how can I declare a binary number in a similar way by putting some leading words to...
3
by: Stephen Mayes | last post by:
Is there any way to represent a literal numerical value in binary? My wish would be something like 0b0011 instead of the hex 0x0F. ( if this is even the same. ) Sometimes I find it's easier to...
4
by: Garry Freemyer | last post by:
I'm trying to convert this macro to a c# function but I have a big problem. It's on the LEFT side of an assignment statement and I am extremely flustered over this one because I'm a little rusty...
7
by: elliotng.ee | last post by:
I have a text file that contains a header 32-bit binary. For example, the text file could be: %%This is the input text %%test.txt Date: Tue Dec 26 14:03:35 2006...
5
by: =?Utf-8?B?YmJkb2J1ZGR5?= | last post by:
I am having a problem converting string to binary and I am hoping someone can help me out I have a sql query that does an update that updates a binary field calles password ...
17
by: osama178 | last post by:
Hi, What does it mean for an object to be binary compatible? And why aren't STL objects binary compatible? Any insights, links, resources for further reading are greatly appreciated. Thanks.
4
by: =?ISO-8859-1?Q?Tom=E1s_=D3_h=C9ilidhe?= | last post by:
Here's a macro that Mathew Hendry posted back in the year 2000 for achieving binary integer literals that evaluate to compile-time constants: #define BIN8(n)\ (((0x##n##ul&1<<...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.