整数减法回绕N位 [英] Integer subtraction with wrap around for N bits
问题描述
基本上,溢流用减法整数时,但对于位的给定数目的你的行为。最显而易见的方法,假设签署整数:
Basically, the behavior you get when overflowing integers with subtraction, but for a given number of bits. The obvious way, assuming a signed integer:
template <int BITS>
int sub_wrap(int v, int s) {
int max = (1<<(BITS));
v -= s;
if (v < -max) v += max*2;
// or if branching is bad, something like:
// v += (max*2) * (v < -max)
return v;
}
// For example subtracting 24 from -16 with 5 bit wrap,
// with a range of -32, 31
sub_wrap<5>(-16, 28); -> 20
是否有这样做是不太丑陋和$ P $比上面的人?
Is there a neat way of doing it that is less ugly and preferably faster than the one above?
更新:很抱歉的混乱。我不假思索地使用包含排除的叹息位的位数的混乱符号。所以在上面,更换6位5位为更大量的理智。
UPDATE: Sorry about the confusion. I thoughtlessly included the confusing notation of using the number of bits excluding the sigh bit. So in the above, replace 5 bits with 6 bits for a lot more sanity.
推荐答案
有关无符号运算,并掩盖的结果,例如:
For unsigned arithmetic, and mask the results, e.g.:
template<int bits>
unsigned
sub_wrap( unsigned v, unsigned s )
{
return (v - s) & ((1 << bits) - 1);
}
更一般地,你可以使用模运算符:
More generally, you can use the modulo operator:
template<int modulo>
unsigned
sub_wrap( unsigned v, unsigned s )
{
return (v - s) % modulo;
}
(包装纸上的 N
位是模相当于2 ^ N)。
(Wrapping on n
bits is the equivalent of modulo 2^n.)
有关签署算术,它更复杂一点;使用面膜,你必须符号扩展的结果(假设2的补数)。
For signed arithmetic, it's a bit more complex; using the mask, you'll have to sign extend the results (supposing 2's complement).
编辑:使用sehe的建议有符号的算术:
Using sehe's suggestion for signed arithmetic:
template<int bits>
int
sub_wrap( int v, int s )
{
struct Bits { signed int r: bits; } tmp;
tmp.r = v - s;
return tmp.r;
}
鉴于此, sub_wrap小于5&GT;(-16,28)
给 -12
(这是正确的&MDASH;注意, 28
不能重新$ p $ 5位psented作为符号int); sub_wrap 6;方式&gt;(-16,28)
给 20
Given this, sub_wrap<5>( -16, 28 )
gives -12
(which is correct—note that 28
cannot be represented as signed int in 5 bits); sub_wrap<6>( -16, 28 )
gives 20
.
这篇关于整数减法回绕N位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!