无符号算术和整数溢出 [英] Unsigned arithmetic and integer overflow
问题描述
我试图了解算术溢出.假设我有以下内容,
I am trying to understand arithmetic overflow. Suppose I have the following,
unsigned long long x;
unsigned int y, z;
x = y*z;
y * z可能导致整数溢出.是否将操作数之一强制转换为unsigned long long可以缓解此问题.将64位操作数与32位操作数相乘的预期结果是什么?
y*z can lead to an integer overflow. Does casting one of the operands to an unsigned long long alleviate this issue. What is the expected result of the multiplication of a 64-bit operand with a 32-bit operand?
推荐答案
unsigned long long x;
unsigned int y, z;
x = y*z;
表达式y*z
的求值不受它出现的上下文的影响.它将两个unsigned int
值相乘,得到一个unsigned int
结果.如果数学结果不能表示为unsigned int
值,则结果将环绕.然后,该赋值将(可能被截断的)结果从unsigned int
隐式转换为unsigned long long
.
The evaluation of the expression y*z
is not affected by the context in which it appears. It multiplies two unsigned int
values, yielding an unsigned int
result. If the mathematical result cannot be represented as an unsigned int
value, the result will wrap around. The assignment then implicitly converts the (possibly truncated) result from unsigned int
to unsigned long long
.
如果您希望乘法运算产生unsigned long long
结果,则需要显式转换一个或两个操作数:
If you want a multiplication that yields an unsigned long long
result, you need to explicitly convert one or both of the operands:
x = (unsigned long long)y * z;
或者,更明确地说:
x = (unsigned long long)y * (unsigned long long)z;
C的*
乘法运算符将 only 应用于相同类型的两个操作数.因此,当您为它提供不同类型的操作数时,在执行乘法运算之前,它们将被转换为某些常见类型.当您混合带符号和无符号类型时,规则可能会有些复杂,但是在这种情况下,如果将unsigned long long
乘以unsigned int
,则会将unsigned int
操作数提升为unsigned long long
.
C's *
multiplication operator applies only to two operands of the same type. Because of this, when you give it operands of different types, they're converted to some common type before the multiplication is performed. The rules can be a bit complex when you're mixing signed and unsigned types, but in this case if you multiply an unsigned long long
by an unsigned int
, the unsigned int
operand is promoted to unsigned long long
.
如果 unsigned long long
的宽度至少是unsigned int
的两倍,是大多数系统上的宽度,那么结果将不会溢出也不会回绕,因为例如64-位unsigned long long
可以保存任何两个32位unsigned int
值相乘的结果.但是,如果您使用的是int
和long long
都为64位宽的系统,则仍然可以使用 overflow 环绕,从而在x
中得到的结果不是等于y
和z
的数学乘积.
If unsigned long long
is at least twice as wide as unsigned int
, as it is on most systems, then the result will neither overflow nor wrap around, because, for example, a 64-bit unsigned long long
can hold the result of multiplying any two 32-bit unsigned int
values. But if you're on a system where, for example, int
and long long
are both 64 bits wide, you can still have overflow wraparound, giving you a result in x
that's not equal to the mathematical product of y
and z
.
这篇关于无符号算术和整数溢出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!