无符号算术和整数溢出 [英] Unsigned arithmetic and integer overflow

查看:194
本文介绍了无符号算术和整数溢出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解算术溢出.假设我有以下内容,

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值相乘的结果.但是,如果您使用的是intlong long都为64位宽的系统,则仍然可以使用 overflow 环绕,从而在x中得到的结果不是等于yz的数学乘积.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆