Вопрос в том, что могут принимать значения 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
s и не рисковать любой смешанной арифметикой, прежде чем быть уверенным в значениях.
И обратите внимание, что на большинстве машин 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;
}
(чуть выше моей головы. Там может быть одно отключение при одной ошибке).