38

I have a function that gets an unsigned long variable as parameter and I want to print it in Hex.

What is the correct way to do it?

Currently, I use printf with "%lx"

void printAddress(unsigned long address) {
    printf("%lx\n", address);
}

Should I look for a printf pattern for unsigned long hex? (and not just "long hex" as mentioned above)

Or does printf convert numbers to hex only using the bits? - so I should not care about the sign anyway?

Edit/Clarification

This question was rooted in a confusion: hex is just another way to express bits, which means that signed/unsigned number is just an interpretation. The fact that the type is unsigned long therefore doesn't change the hex digits. Unsigned just tells you how to interpret those same bits in your computer program.

SomethingSomething
  • 11,491
  • 17
  • 68
  • 126
  • 1
    Please consult the friendly documentation. – Kerrek SB Apr 08 '15 at 08:22
  • 2
    What problem are you facing with `%lx` ? This should be fine for an unsigned long. Of course if your `address` parameter really is an address then you should probably be passing it as `void *` and printing it with `%p`. – Paul R Apr 08 '15 at 08:26
  • This `address` is not a real pointer in a C program - it is an address of a simulated machine, not always in the same size as a pointer on my machine. – SomethingSomething Apr 08 '15 at 08:29
  • 2
    What `printf` lacks is a way to print _signed hexadecimal numbers_... – rodrigo Apr 08 '15 at 08:30
  • I did not get a problem yet, but I'm afraid that with too high values, it will see it as "long" and not as "unsigned long" – SomethingSomething Apr 08 '15 at 08:30
  • @KerrekSB, my question was probably not written very well. My actual question was whether I can use "%lx" even though the type is unsigned. I don't think it is so trivial – SomethingSomething Apr 08 '15 at 08:49
  • 1
    Actually I now see that in cplusplus.com it is written very boldly that "x" is unsigned hex. You were right, my question is not very useful... – SomethingSomething Apr 08 '15 at 08:52
  • 1
    @SomethingSomething: As the accepted answer demonstrates, it is actually exactly trivial, i.e. the manual contains a straight-forward answer to your question. Posting on Stack Overflow added nothing. – Kerrek SB Apr 08 '15 at 09:26
  • sign should not matter, since Hex is just another way to represent bits. It is up to you to decide whether to interpret the bits as a signed or an unsigned number – SomethingSomething Jun 13 '19 at 10:01
  • It's funny to see that people still ask themselves this question and reach this thread. Hex is just a higher-level representation of bits, which are of course not related to the sign. The signed/unsigned is just an interpretation :) – SomethingSomething Sep 06 '19 at 19:27
  • "sign should not matter, since Hex is just another way to represent bits." is incorrect. `"%lx"` matches `unsigned long` which is never negative. C lacks a specify to print `long` with a negative value in "hex". To print `-100L` in hex requires other code to print correctly in hexadecimal. – chux - Reinstate Monica Mar 02 '21 at 22:02
  • @chux-ReinstateMonica I was trying to say that interpreting the bits as signed/unsigned is up to you. Some combinations of bits can be interpreted as very large positive numbers, or as negative numbers, depending on whether you use signed/unsigned type to interpret them. The bits themselves have no sign, and hex is just another way to represent bits, so it shouldn't have a sign either. By using `"%lx"` you simply tell `printf` to print 64 bits in hex. Am I wrong? – SomethingSomething Mar 03 '21 at 11:10
  • @SomethingSomething Passing a negative `long` and printing via `"%lx:` is undefined behavior. The code need not print based on a sign agnostic bit pattern, nor not print at all, it is UB. With `"%lx"`, pass an `unsigned long`. – chux - Reinstate Monica Mar 03 '21 at 12:57

2 Answers2

36

You're doing it right.

From the manual page:

o, u, x, X

The unsigned int argument is converted to unsigned octal (o), unsigned decimal (u), or unsigned hexadecimal (x and X) notation.

So the value for x should always be unsigned. To make it long in size, use:

l

(ell) A following integer conversion corresponds to a long int or unsigned long int argument [...]

So %lx is unsigned long. An address (pointer value), however, should be printed with %p and cast to void *.

unwind
  • 391,730
  • 64
  • 469
  • 606
10

I think the following format specifier should work give it a try

printf("%#lx\n",address);

Himanshu Sourav
  • 700
  • 1
  • 10
  • 35
  • 9
    Close, but no cigar! Either use `printf("0x%lx\n",address);` or `printf("%#lx\n",address);` but not both. The first will print the value `0UL` as `0x0` while the second will just output `0`. This suggestion will teach the OP something but is unrelated to the question. – chqrlie Apr 08 '15 at 08:48