6

Please see the simple code below:

#include <iostream>
#include <stdlib.h>

using namespace std;


int main(void)
{
    unsigned long currentTrafficTypeValueDec;
    long input;
    input=63;
    currentTrafficTypeValueDec = (unsigned long) 1LL << input; 
    cout << currentTrafficTypeValueDec << endl;
    printf("%u \n", currentTrafficTypeValueDec);
    printf("%ld \n", currentTrafficTypeValueDec);
    return 0;
}

Why printf() displays the currentTrafficTypeValueDec (unsigned long) with negative value?

The output is:

9223372036854775808
0
-9223372036854775808 
Grzegorz Adam Kowalski
  • 5,243
  • 3
  • 29
  • 40
user292167
  • 187
  • 1
  • 4
  • 14
  • Possible duplicate of https://stackoverflow.com/questions/1831753/c-unsigned-int-providing-a-negative-value ? – user202729 Oct 19 '18 at 11:04

6 Answers6

19

%d is a signed formatter. Reinterpreting the bits of currentTrafficTypeValueDec (2 to the 63rd power) as a signed long gives a negative value. So printf() prints a negative number.

Maybe you want to use %lu?

Mike DeSimone
  • 41,631
  • 10
  • 72
  • 96
14

You lied to printf by passing it an unsigned value while the format spec said it would be a signed one.

AProgrammer
  • 51,233
  • 8
  • 91
  • 143
5

Because you're shifting the 1 into the sign bit of the variable. When you print it as a signed value, it's negative.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760
5

Fun with bits...

cout is printing the number as an Unsigned Long, all 64 bits are significant and print as unsigned binary integer (I think the format here would be %lu).

printf(%u ... treats the input as an normal unsigned integer (32 bits?). This causes bits 33 through 64 to drop off - leaving zero.

printf(%ld ... treats the input as a 64 bit signed number and just prints it out as such.

The thing you might find confusing about the last printf is that it gives the same absolute value as cout, but with a minus sign. When viewing as an unsigned integer all 64 bits are significant in producing the integer value. However for signed numbers, bit 64 is the sign bit. When the sign bit is set (as it is in your example) it indicates the remaining 63 bits are to be treated as a negative number represented in 2's compliment. Positive numbers are printed simply by converting their binary value to decimal. However for a negative number the following happens: Print a negative sign, XOR bits 1 through 63 with binary '1' bits, add 1 to the result and print the unsigned value. By dropping the sign bit (bit 64) you end up with 63 '0' bits, XORing with '1' bits gives you 63 '1' bits, add +1 and the whole thing rolls over to give you an unsigned integer having bit 64 set to '1' and the rest set to '0' - which is the same thing you got with cout BUT, as a negative number.

Once you have worked out why the above explanation is correct you should also be able to make sense out of this

NealB
  • 16,670
  • 2
  • 39
  • 60
2

the variable doesn't carry its type in itself. You specify to printf its type. Try:

printf("%lu \n", currentTrafficTypeValueDec);

because ld meand long signed that is not true.

Carl Manaster
  • 39,912
  • 17
  • 102
  • 155
Andrey
  • 59,039
  • 12
  • 119
  • 163
0

You're printing %ld, or a long signed decimal. That's why it's returning a negative value.

user266117
  • 56
  • 1
  • 5