gpt4 book ai didi

c++ - 是否有一个表达式使用模来进行反向环绕 ("reverse overflow")?

转载 作者:IT老高 更新时间:2023-10-28 22:00:31 24 4
gpt4 key购买 nike

对于任何受范围 R = [x,y] 限制的整数输入 W, “溢出”,由于没有更好的术语,W 超过 RW % (y-x+1) + x。如果 W 超过 y,这会导致它回绕。

作为这个原则的一个例子,假设我们遍历一个日历的月份:

int this_month = 5;
int next_month = (this_month + 1) % 12;

其中两个整数都介于 0 和 11 之间,包括 0 和 11。因此,上面的表达式将整数“钳制”在 R = [0,11] 的范围内。这种使用表达式的方法简单、优雅且有利,因为它省略了分支

现在,如果我们想做同样的事情,但反过来呢?以下表达式有效:

int last_month = ((this_month - 1) % 12 + 12) % 12;

但它很深奥。怎么美化?


tl;dr - 表达式 ((x-1) % k + k) % k 可以进一步简化吗?

注意:指定 C++ 标记是因为其他语言对模运算符的负操作数处理方式不同。

最佳答案

你的表达式应该是((x-1) + k) % k。这将正确地将 x=0 环绕到 11。通常,如果您想退后超过 1,则需要确保添加足够多,以使模运算的第一个操作数 >= 0。

这是 C++ 中的一个实现:

int wrapAround(int v, int delta, int minval, int maxval)
{
const int mod = maxval + 1 - minval;
if (delta >= 0) {return (v + delta - minval) % mod + minval;}
else {return ((v + delta) - delta * mod - minval) % mod + minval;}
}

这也允许使用从 0 到 11 或从 1 到 12 标记的月份,相应地设置 min_valmax_val

由于这个答案非常受欢迎,这里有一个没有分支的改进版本,它也可以处理初始值 v 小于 minval 的情况。我保留另一个示例,因为它更容易理解:

int wrapAround(int v, int delta, int minval, int maxval)
{
const int mod = maxval + 1 - minval;
v += delta - minval;
v += (1 - v / mod) * mod;
return v % mod + minval;
}

剩下的唯一问题是 minval 是否大于 maxval。如果需要,请随意添加断言。

关于c++ - 是否有一个表达式使用模来进行反向环绕 ("reverse overflow")?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14785443/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com