计算两个无符号整数之差的绝对值时如何防止溢出?
结果也必须是无符号整数(实际上独立于处理器,因为它在数学上只是 0 到 MAXINT 之间的数字)。
unsigned int a;
unsigned int b;
abs(a-b);
但这仅在 b<=a, otherwise a-b<0 and will then overflow, and taking
abs
稍后无济于事时才有效。
进行该计算的最简单且不会溢出的方法是什么?
(其实我想测试是否|a-b|
感谢评论中的答案,人们看到可以像使用案例区分一样完成一个简单的解决方案。
unsigned int uint_diff(unsigned int a, unsigned int b){
if (a > b){
return (a - b);
}
else {
return (b - a);
}
}
您可以使用简单的转换 如果
long long signed int
大于您平台上的 unsigned int
。它“可能”会是,但标准确实允许 int
、long
和 long long
具有相同的大小。 (注:我特别使用了
long long
,因为在一些常见平台上 – 如 MSVC/Windows – long int
与 int
大小相同,对于 unsigned
版本也是如此。)
这是一个使用 constexpr if
(编译时)检查的版本,如果转换不起作用,则使用更简单的测试优先解决方案:
#include <iostream>
#include <cmath>
unsigned int unsint_diff(unsigned int a, unsigned int b)
{
if constexpr (sizeof(long long int) > sizeof(unsigned int)) {
return static_cast<unsigned int>(std::abs(static_cast<long long signed int>(a) - b));
}
else {
if (a > b) return a - b;
else return b - a;
}
}
int main()
{
unsigned int i = 123456789u;
unsigned int j = 987654321u;
std::cout << unsint_diff(i, j) << "\n";
std::cout << unsint_diff(j, i) << "\n";
return 0;
}
如果
long long signed int
类型足够大,可以容纳
unsigned int
类型的 所有可能值(如果它至少大一个字节的话),那么您只需要对以下操作数之一进行强制转换进行减法,因为在这种情况下,unsigned int
的等级低于 long long int
,并且会在运算前提升为该类型。您可以使用简单的转换 如果
long long signed int
大于您平台上的 unsigned int
。它“可能”会是,但标准确实允许 int
、long
和 long long
具有相同的大小。 (注:我特别使用了
long long
,因为在一些常见平台上 – 如 MSVC/Windows – long int
与 int
大小相同,对于 unsigned
版本也是如此。)
这是一个使用 constexpr if
(编译时)检查的版本,如果转换不起作用,则使用更简单的测试优先解决方案:
#include <iostream>
#include <cmath>
unsigned int unsint_diff(unsigned int a, unsigned int b)
{
if constexpr (sizeof(long long int) > sizeof(unsigned int)) {
return static_cast<unsigned int>(std::abs(static_cast<long long signed int>(a) - b));
}
else {
if (a > b) return a - b;
else return b - a;
}
}
int main()
{
unsigned int i = 123456789u;
unsigned int j = 987654321u;
std::cout << unsint_diff(i, j) << "\n";
std::cout << unsint_diff(j, i) << "\n";
return 0;
}
如果
long long signed int
类型足够大,可以容纳
unsigned int
类型的 所有可能值(如果它至少大一个字节的话),那么您只需要对以下操作数之一进行强制转换进行减法,因为在这种情况下,unsigned int
的等级低于 long long int
,并且会在运算前提升为该类型。