提问人:pas-calc 提问时间:10/22/2023 最后编辑:Adrian Molepas-calc 更新时间:10/22/2023 访问量:165
如何计算两个无符号整数的绝对差?
How to calculate the absolute difference of two unsigned integers?
问:
在计算两个无符号整数之差的绝对值时,如何防止溢出?
结果也必须是一个无符号整数(实际上与处理器无关,因为它在数学上只是一个介于 0 和 MAXINT 之间的数字)。
unsigned int a;
unsigned int b;
abs(a-b);
但这只有在 b<=a 时才有效,否则 a-b<0 然后会溢出,以后服用也无济于事。abs
进行该计算的最简单、最安全的方法是什么?
(实际上我想测试 |a-b|<c 是否 其中 c 是某个常数。 因此,可以检查 a-bb 和 b-aa。
答:
2赞
pas-calc
10/22/2023
#1
多亏了评论中的答案,人们看到一个简单的解决方案可以像使用大小写区分一样完成。
unsigned int uint_diff(unsigned int a, unsigned int b){
if (a > b){
return (a - b);
}
else {
return (b - a);
}
}
评论
0赞
Alexei Levenkov
10/22/2023
显然违背了 OP 的要求——“我本来会期待一些没有 if/else 但纯类型铸造的东西”。
1赞
Adrian Mole
10/22/2023
@AlexeiLevenkov 但这个回答者是OP;)
0赞
Alexei Levenkov
10/22/2023
@AdrianMole我知道:)......有时 OP 需要提醒,答案实际上应该按要求回答问题,而不是为他们实际需要做的任何事情写答案......
0赞
Adrian Mole
10/22/2023
#2
如果平台上的 a 大于 an,则可以使用简单的强制转换。它可能会,但标准确实允许 ,并且大小相同。(注意:我特别使用 long long,因为在一些常见的平台(如 MSVC/Windows)上,long
int 的大小与 int
相同,对于
未签名
的版本也是如此。long long signed int
unsigned int
int
long
long long
下面是一个使用(编译时)检查的版本,如果两个强制转换都不起作用,则回退到更简单的测试优先解决方案:constexpr if
#include <iostream>
#include <cmath>
unsigned int unsint_diff(unsigned int a, unsigned int b)
{
if constexpr (sizeof(long int) > sizeof(unsigned int)) {
return static_cast<unsigned int>
(std::abs(static_cast<long signed int>(a) - static_cast<long signed int>(b)));
}
else if constexpr (sizeof(long long int) > sizeof(unsigned int)) {
return static_cast<unsigned int>
(std::abs(static_cast<long long signed int>(a) - static_cast<long long signed int>(b)));
}
else {
return (a > b) ? a - b : 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;
}
请注意,您需要对减法的两个操作数进行强制转换,因为如果大小比较不“成功”,那么调用将使用一个参数 - 这是模棱两可的,因此,代码格式不正确(这是不允许的,即使在实际不会使用的语句的正文中)。std::abs
unsigned int
if constexpr
评论
if (a > b) return a - b; else return b - a;
if
? ... : ...
(a > b) ? (a - b) : (b - a)