N 位环绕的整数减法
基本上,这是在给定位数的情况下通过减法溢出整数时得到的行为。显而易见的方法,假设一个有符号整数:
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
是否有一种简洁的方法可以比上面的方法更简洁、更快?
更新:很抱歉造成混乱。我不假思索地添加了使用不包括叹息位的位数的令人困惑的符号。因此,在上面的内容中,将 5 位替换为 6 位,以便更加理智。
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
Is there a neat way of doing it that is less ugly and preferably faster than the one above?
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
对于无符号算术,并屏蔽结果,例如:
更一般地,您可以使用模运算符:(
包裹在
n
位上相当于模2^n。)对于有符号算术,它是一个位更复杂;使用掩码,您必须对结果进行签名扩展(假设 2 的补码)。
编辑:使用 sehe 对有符号算术的建议:
鉴于此,
sub_wrap<5>( -16, 28 )
给出-12
(这是正确的 - 请注意28
不能表示为 5 位的有符号 int);sub_wrap<6>( -16, 28 )
给出20
。For unsigned arithmetic, and mask the results, e.g.:
More generally, you can use the modulo operator:
(Wrapping on
n
bits is the equivalent of modulo 2^n.)For signed arithmetic, it's a bit more complex; using the mask, you'll have to sign extend the results (supposing 2's complement).
EDIT: Using sehe's suggestion for signed arithmetic:
Given this,
sub_wrap<5>( -16, 28 )
gives-12
(which is correct—note that28
cannot be represented as signed int in 5 bits);sub_wrap<6>( -16, 28 )
gives20
.我想这应该可行:
我很确定字段宽度不适用于 const 模板参数...因此这不太通用。但是,它应该避免手动修补。很快就会发布测试更新 事实证明我的答案并没有错。只是样本输入(28)无法用 5 位(有符号)表示。上述结果是-12(参见http://ideone.com/AUrXy)。
为了完整起见,这里毕竟是一个模板版本:
I suppose this should work:
I'm pretty sure the field width won't work with a const template argument... and hence this is less generic. It should, however, avoid manual tinkering. Will post test soonUpdate It turns out my answer wasn't incorrect after all. It is just that the sample input (28) cannot be represented in 5 bits (signed). The outcome of the above is -12 (see http://ideone.com/AUrXy).
Here is, for completeness, a templated version after all:
以下是我在没有条件分支和乘法的情况下如何做到这一点:
输出:
Here's how I'd do it w/o conditional branches and multiplication:
Output:
这模拟了 n 位整数运算:
结果:
看来您错误地计算了 1 位的类型大小。
This simulates an n bit integer operation:
Results:
Seems you miscalculated your type size by 1 bit.