tags:

views:

158

answers:

6

I read the documentation and it says that a long is %li but the print out comes back as -2147024891. What gives?

+8  A: 

You didn't even provide which number you wanted to print, but I guess you've stumbled over the difference between signed and unsigned printing.

Use "%lu" for unsigned long numbers, and "%ld" or "%li" for signed long numbers.

The MSDN has good documentation on printf specifiers. For 64-bit values (like long long, for example), you should use the macros in "inttypes.h".

AndiDog
A: 

Are you printing a unsigned value as signed? With two's complement, a value with the most significant bit set will be printed as a negative. Try %u for unsigned

mrjoltcola
"%u" is for the `unsigned int` type. The OP asked for printing `long` numbers.
AndiDog
A: 

%ld or %lu depending on the 'long' you need.

Matt
+3  A: 

You are trying to print an HRESULT, the error code for "access denied". That is best formatted in hex, at least to be easily recognizable to a programmer.

printf("0x%08lx", hr);

Now you'll instantly recognize the facility code 7 (Windows API) and the error code 5 (access denied).

Hans Passant
+1 For the nice observation. I'd point out though that an HRESULT is always 32-bits. The pendantician (can I say this word?) in me wants to point out that you should always use the fixed width macros for... well... fixed width integers, i.e. `printf("0x%08"PRIx32, hr);` in this case. The fact that Microsoft seems to not care about C99 is a side issue that I'd care not to acknowledge as relevant ;)
Dan Moulding
The OP is correct, HRESULT is typedef-ed to LONG. Using %lx is not wrong.
Hans Passant
@nobugz: You're right. It's typedef-ed to LONG, but LONG is specifically defined as, "32-bit signed integer. The range is –2147483648 through 2147483647 decimal."
Dan Moulding
A: 

Given the code:

#include <stdio.h>
int main(void)
{
    long l1 = +2147024891;
    long l2 = -2147024891;
    printf("%+11li = 0x%lx\n", l1, l1);
    printf("%+11li = 0x%lx\n", l2, l2);
    return(0);
}

The output compiled in 32-bit mode (on MacOS 10.6.2) is:

+2147024891 = 0x7ff8fffb
-2147024891 = 0x80070005

The output compiled in 64-bit mode is:

 2147024891 = 0x7ff8fffb
-2147024891 = 0xffffffff80070005

Since you don't show us what you wrote and why you expected something different, it is hard to say what could be wrong. However, although relatively unusual, the '%li' conversion was in C89 as well as C99, so that should be correct. The more normal conversion specifiers are '%ld' (a synonym of '%li') and '%lu' (and '%lo' and '%lx') for unsigned values.

Jonathan Leffler
A: 

Try %llu and also for assigning a value to a long variable dont forget you must add "LL" in the end of the number, for instance a=999999999LL

Erethon