使用"uint_64t"添加"int"
adding "int" with "uint_64t"
有三个变量具有以下类型
uint64_t old_addr, new_addr;
int delta;
我想做这个作业
new_addr = old_addr + delta;
然而问题是,当old_addr=915256
和delta=-6472064
时,new_addr
变得18446744069414584325
要解决这个问题,我必须检查一些事情:
if ( delta < 0 ) {
if ( old_addr < abs(delta) )
new_addr = 0;
else
new_addr = old_addr + delta;
}
有没有更好、更有效的方法?
这称为饱和加法,某些处理器对此有特殊的机器指令。您可以将该代码提取到内联函数中,并根据目标执行环境使用机器指令。
您可以简单地写-delta
而不是abs(delta)
,因为您已经知道delta < 0
.
问题是old_addr
和new_addr
可以接受什么价值观。 以及为什么它们是uint64_t
的,而不是简单的int
。 最简单的表达式将:
new_addr = old_addr + std::min( delta, -static_cast<int>( old_addr ) );
,但如果old_addr
可以大于 INT_MAX
,这将不起作用。否则,C/C++ 中混合有符号/无符号算术的规则为这样您可能使用显式if
最安全,并且不会冒险在确定值之前的任何混合算术。
请注意,在大多数机器上,abs( delta )
如果 delta
等于 INT_MIN
. 为了正确处理所有情况,你需要这样的东西:
if ( delta > 0 ) {
new_addr = std::numeric_limits<uin64_t>::max() - delta > old_addr
? old_addr + delta
: std::numeric_limits<uint64_t>::max();
} else if ( delta < 0 ) {
new_addr = old_addr != 0 && -(delta + 1) < old_addr - 1
? old_addr + delta
: 0;
} else {
new_addr = old_addr;
}
(就在我头顶上。 很容易出现一个错误在那里。
这段代码非常简单,可以处理两个方向的溢出。
#include <assert.h>
#include <inttypes.h>
#include <stdint.h>
static uint64_t saturated_add(uint64_t a, int delta) {
uint64_t result = a + delta;
if (delta < 0 && result > a) {
return 0;
} else if (delta > 0 && result < a) {
return -1;
} else {
return result;
}
}
int main() {
assert(saturated_add(915256, -6472064) == 0);
assert(saturated_add(100, -99) == 1);
assert(saturated_add(100, -100) == 0);
assert(saturated_add(100, -101) == 0);
assert(saturated_add(UINT64_C(0x1111222233334444), -0x33334445) == UINT64_C(0x11112221FFFFFFFF));
assert(saturated_add(-5, 6) == UINT64_C(-1));
assert(saturated_add(-5, 5) == UINT64_C(-1));
assert(saturated_add(-5, 4) == UINT64_C(-1));
assert(saturated_add(-5, 3) == UINT64_C(-2));
return 0;
}
相关文章:
- 将布尔变量添加到 int
- 如果 x < 10,则添加前导 0 并将其存储为 int
- "Missing type specifier - int assumed"无法通过向主函数添加"return 0"来解决
- 赋值和添加运算符重载(2个表和int的串联)
- 向size_t添加 int 的正确方法
- C++在减去 int 时向 int 添加一个额外的数字
- 尝试将 char* 添加到 int 时触发编译器错误
- 将map<pair<int,int>,vector<Object> >添加到BST中,其中对是关键
- 如何在类/类型中添加更多函数来构建 int、double、std::string 等
- 当我向 vector<int *> 添加元素时,我遇到了一些问题
- 重载 + 运算符以使用 int 添加对象
- OpenMP增量在线程之间添加int
- 从矢量 c++ 添加 int 元素时出错
- 在c++中添加int数组时,试图找出堆栈损坏的问题
- 使用"uint_64t"添加"int"
- Memcpy:添加int偏移量
- 向数组中添加int,将LSB转换为0 c++
- 向char数组中添加int类型
- 操作符重载c++在对象中添加int
- 使用Rcpp::IntegrVectors添加int