在 C++ 中使用所有 32 位整数的算术溢出?
Arithmetic overflow using all 32-bit ints in C++?
这应该只是将 1 加到 unsigned int 上:prev = nums[nextIndex + 1];
但它会发出警告说
Arithmetic overflow: Using operator '+' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator '+' to avoid overflow
但我没有使用任何 8 字节值,它们都是 32 位整数...为什么它为我将内容转换为 8 字节值?
我在 LeetCode 上做一些问题,所以这里是我正在做的问题的完整代码,只是旋转一个整数向量:
void rotate(std::vector<int>& nums, int k) {
k %= nums.size();
if (k > 0) {
unsigned int offsetCounter = 0;
int prev;
int next = nums[0];
for (unsigned int i = 0; i < nums.size(); i++) {
int f = k * i;
unsigned int nextIndex = ((unsigned int)((unsigned int)k * ((unsigned int)i + (unsigned int)1)) + (unsigned int)offsetCounter) % (unsigned int)nums.size();
if (nextIndex == offsetCounter) {
offsetCounter++;
prev = nums[nextIndex + 1];
}
else
{
prev = nums[nextIndex];
}
nums[nextIndex] = next;
next = prev;
}
}
}
nextIndex
也给出了同样的警告,唯一摆脱它的是将所有内容都转换为无符号整数。我不明白为什么它说我使用的是 8 字节值,而我绝对没有使用 8 字节值。我过去忽略过这样的警告,但 LeetCode 非常重视它们。谢谢。
矢量索引(和 std::vector::size()
)是 size_t
,而不是 unsigned int
,这就是您的问题所在。
要解决此问题,请将所有 unsigned int
变量声明为 size_t
并删除所有这些强制转换:
void rotate(std::vector<int>& nums, size_t k) {
k %= nums.size();
if (k > 0) {
size_t offsetCounter = 0;
int prev;
int next = nums[0];
for (size_t i = 0; i < nums.size(); i++) {
size_t nextIndex = (k * i + 1 + offsetCounter) % nums.size();
if (nextIndex == offsetCounter) {
offsetCounter++;
prev = nums[nextIndex + 1];
}
else
{
prev = nums[nextIndex];
}
nums[nextIndex] = next;
next = prev;
}
}
}
operator[]
在 std::vector
中定义为
constexpr reference operator[]( size_type pos );
加上几个类似的重载,都采用 std::vector
定义的 size_type
类型的参数。 Cppreference.com 关于这种类型的说法是这样的:
Unsigned integer type (usually std::size_t)
关于std::size_t
的解释(部分):
std::size_t is commonly used for array indexing and loop counting. Programs that use other types, such as unsigned int, for array indexing may fail on, e.g. 64-bit systems when the index exceeds UINT_MAX or if it relies on 32-bit modular arithmetic.
When indexing C++ containers, such as std::string, std::vector, etc, the appropriate type is the member typedef size_type provided by such containers. It is usually defined as a synonym for std::size_t.
因此:std::vector
使用通常等同于 std::size_t
的类型进行索引,在您的计算机上它是一个 64 位无符号整数。
因此,如果您希望警告消失,您可以将 nextIndex
定义为 64 位无符号整数,例如
unsigned long nextIndex
或
size_t nextIndex;
std::vector<int>::size_type nextIndex;
或使用类型为 unsigned ling long
:
的常量强制转换
prev = nums[nextIndex + 1ull];
这应该只是将 1 加到 unsigned int 上:prev = nums[nextIndex + 1];
但它会发出警告说
Arithmetic overflow: Using operator '+' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator '+' to avoid overflow
但我没有使用任何 8 字节值,它们都是 32 位整数...为什么它为我将内容转换为 8 字节值?
我在 LeetCode 上做一些问题,所以这里是我正在做的问题的完整代码,只是旋转一个整数向量:
void rotate(std::vector<int>& nums, int k) {
k %= nums.size();
if (k > 0) {
unsigned int offsetCounter = 0;
int prev;
int next = nums[0];
for (unsigned int i = 0; i < nums.size(); i++) {
int f = k * i;
unsigned int nextIndex = ((unsigned int)((unsigned int)k * ((unsigned int)i + (unsigned int)1)) + (unsigned int)offsetCounter) % (unsigned int)nums.size();
if (nextIndex == offsetCounter) {
offsetCounter++;
prev = nums[nextIndex + 1];
}
else
{
prev = nums[nextIndex];
}
nums[nextIndex] = next;
next = prev;
}
}
}
nextIndex
也给出了同样的警告,唯一摆脱它的是将所有内容都转换为无符号整数。我不明白为什么它说我使用的是 8 字节值,而我绝对没有使用 8 字节值。我过去忽略过这样的警告,但 LeetCode 非常重视它们。谢谢。
矢量索引(和 std::vector::size()
)是 size_t
,而不是 unsigned int
,这就是您的问题所在。
要解决此问题,请将所有 unsigned int
变量声明为 size_t
并删除所有这些强制转换:
void rotate(std::vector<int>& nums, size_t k) {
k %= nums.size();
if (k > 0) {
size_t offsetCounter = 0;
int prev;
int next = nums[0];
for (size_t i = 0; i < nums.size(); i++) {
size_t nextIndex = (k * i + 1 + offsetCounter) % nums.size();
if (nextIndex == offsetCounter) {
offsetCounter++;
prev = nums[nextIndex + 1];
}
else
{
prev = nums[nextIndex];
}
nums[nextIndex] = next;
next = prev;
}
}
}
operator[]
在 std::vector
中定义为
constexpr reference operator[]( size_type pos );
加上几个类似的重载,都采用 std::vector
定义的 size_type
类型的参数。 Cppreference.com 关于这种类型的说法是这样的:
Unsigned integer type (usually std::size_t)
关于std::size_t
的解释(部分):
std::size_t is commonly used for array indexing and loop counting. Programs that use other types, such as unsigned int, for array indexing may fail on, e.g. 64-bit systems when the index exceeds UINT_MAX or if it relies on 32-bit modular arithmetic.
When indexing C++ containers, such as std::string, std::vector, etc, the appropriate type is the member typedef size_type provided by such containers. It is usually defined as a synonym for std::size_t.
因此:std::vector
使用通常等同于 std::size_t
的类型进行索引,在您的计算机上它是一个 64 位无符号整数。
因此,如果您希望警告消失,您可以将 nextIndex
定义为 64 位无符号整数,例如
unsigned long nextIndex
或size_t nextIndex;
std::vector<int>::size_type nextIndex;
或使用类型为 unsigned ling long
:
prev = nums[nextIndex + 1ull];