[英]unsigned int(32bit) to unsigned long long (64bit)
In the code below, I multiplied 0xffffffff
by 2 for an unsigned int
(32bit) and stored it in a unsigned long long
(64bit). 在下面的代码中,我将
0xffffffff
乘以2表示unsigned int
(32位)并将其存储在unsigned long long
(64位)中。 Why don't I get the actual output which is 8589934588
. 为什么我得不到
8589934588
的实际输出。 Instead I get 4294967294
. 相反,我得到
4294967294
。 Thanks in advance. 提前致谢。 OUTPUT: Sizeof i=4 Sizeof J=8 2xi=4294967292
输出: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. 这是因为
i*2
是整数乘法。 Even though you're storing it in a long long
, you're still doing integer math, which causes an overflow. 即使你将它存储
long long
,你仍然在进行整数运算,这会导致溢出。
The following code works, as we promote it up to long long
multiply 以下代码有效,因为我们将其推广到
long long
乘法
#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. i*2
对它被分配给unsigned long long
这一事实一无所知 - 因为i
是unsigned int
, 2
是int
,乘法是使用unsigned int
类型执行的,这产生了你得到的结果。
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: 你可以通过使
2
成为unsigned long long
文字来解决问题,它将i
提升为unsigned long long
乘法,或者在乘法之前将i
为unsigned long long
,具有相同的效果:
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. 通常,请记住:在C中,赋值/初始化的目标不影响如何计算右边的表达式 - 所涉及的类型仅由操作数的类型决定。
Since i
is an unsigned int
and 2
is an int
and will be promoted to unsigned int
the operation will just wrap around. 因为
i
是一个unsigned int
而且2
是一个int
并且将被提升为unsigned int
所以操作将只是换行。 One solution would be to cast i
to unsigned long long
: 一种解决方案是将
i
为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
: C11标准草案的相关部分见
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.
涉及无符号操作数的计算永远不会溢出,因为无法通过生成的无符号整数类型表示的结果将以比结果类型可以表示的最大值大1的数量为模。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.