문제

In the code below, I multiplied 0xffffffff by 2 for an unsigned int(32bit) and stored it in a unsigned long long(64bit). Why don't I get the actual output which is 8589934588. Instead I get 4294967294. Thanks in advance. OUTPUT: Sizeof i=4 Sizeof J=8 2xi=4294967292

/* Code starts here */
#include <stdio.h>
#include <stdlib.h>

int main (void) 
{
    unsigned int i=4294967294;
    unsigned long long j=i*2;
    printf("Sizeof i=%d\n", sizeof(i));
    printf("Sizeof J=%d\n", sizeof(j));
    printf("2xi=%llu\n", j);

    return 0;
}
도움이 되었습니까?

해결책

It's because the i*2 is integer multiply. Even though you're storing it in a long long, you're still doing integer math, which causes an overflow.

The following code works, as we promote it up to long long multiply

#include <stdio.h>
#include <stdlib.h>
int main (void)
{
  unsigned int i=4294967294;
  unsigned long long j=((unsigned long long)i)*2;
  printf("Sizeof i=%d\n", sizeof(i));
  printf("Sizeof J=%d\n", sizeof(j));
  printf("2xi=%llu\n", j);

  return 0;
}

Result:

bash-4.1$ gcc long.c
bash-4.1$ ./a.out
Sizeof i=4
Sizeof J=8
2xi=8589934588

다른 팁

i*2 knows nothing about the fact that it's being assigned to an unsigned long long - since i is an unsigned int and 2 is an int the multiplication is performed using the unsigned int type, which yields the result you got.

You can fix the problem by making 2 an unsigned long long literal, which promotes i to unsigned long long for the multiplication, or casting i to unsigned long long before the multiplication, which has the same effect:

unsigned long long j=i*2ULL;
/* or */
unsigned long long j=((unsigned long long)i)*2;

In general, remember: in C the target of an assignment/initialization does not affect how the expression to its right is computed - the types involved are determined only by the types of the operands.

Since i is an unsigned int and 2 is an int and will be promoted to unsigned int the operation will just wrap around. One solution would be to cast i to unsigned long long:

unsigned long long j = ((unsigned long long)i)*2 ;

The relevant section from the draft C11 standard is in 6.2.5/9:

A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top