Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
557 views
in Technique[技术] by (71.8m points)

c - Is unsigned long int correct for this operation?

Here's my code:

#include <stdio.h>

int main(int argc, char *argv[]) {

    unsigned long int x = 0;

    // trying to make x = 2,147,483,648
    x = 1 << 31;

    printf("%lu", x);
}

It's returning that x = 18446744071562067968. I read that unsigned long int should go up to 4,294,967,296, so why can't I use 1 << 32 to set x equal to 2,147,483,648?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

1 << 31 causes undefined behaviour, if your system has 32-bit ints. The literal 1 is a signed int.

You need to do an unsigned shift instead of a signed shift:

x = 1UL << 31;

I added L so that the code is still correct even on a 16-bit system, and it doesn't hurt to do so.


Informally, shifting a 1 into the sign bit is undefined. The formal text can be found in section 6.5.7/4 of the C11 standard:

The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. [...] If E1 has a signed type and nonnegative value, and E1 × 2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.


Your other question, "why can't I use 1 << 32" is covered by that same quote. What about 1UL << 32 ? If your system has 32-bit unsigned long then this would also be undefined according to 6.5.7/3:

[...] If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined

But it would work if your system had 64-bit unsigned long. To avoid having your code break when compiled on a different system (this goal is known as code portability) you could write (uint64_t)1 << 32 (or 1ULL << 32) which is guaranteed to work.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...