基于最大值的换行/溢出数的算法

Posted

技术标签:

【中文标题】基于最大值的换行/溢出数的算法【英文标题】:An algorithm to wrap/overflow number based on max value 【发布时间】:2013-01-10 15:32:35 【问题描述】:

有人来挑战吗?我正在寻找一种有效的算法来实现固定最大值的数字的换行/溢出行为。

说,最大可能的数值定义为:

#define MAX_NUMBER_VALUE 100

还有一个函数translate,它接受一个带符号的 32 位或 64 位整数值,并使用 MAX_NUMBER_VALUE 常量“环绕”它:

int_fast8_t translate(int_fast32_t value) 

  if (abs(value) > MAX_NUMBER_VALUE) 
    return ...; // This!
  

  return value;

预期的输入和输出:

translate(55)   => 55
translate(100)  => 100
translate(101)  => -100
translate(102)  => -99
translate(200)  => -1
translate(202)  => 1
translate(300)  => 99
translate(-40)  => -40
translate(-100) => -100
translate(-101) => 100
translate(-102) => 99
translate(-200) => 1
translate(-201) => 0
...

值围绕数字“走动”,就好像它是一个圆形行星。这看起来确实类似于 C/C++ 处理 int 溢出条件的方式。我想知道是否有一种快速有效的方法来实现这种包装?像移位或其他按位运算一样?

【问题讨论】:

您是在描述% 运算符吗? 你基本上需要对MAX_NUMBER_VALUE*2 - 1做一个模数... 【参考方案1】:

听起来您只是在描述% 运算符,并对负数进行了一些仔细的处理。

【讨论】:

您应该详细说明这种“小心处理负数” - 这是我认为问题的重要方面。我怀疑答案是否会非常有用。 是的,我很清楚模运算符在这里很可能是不可避免的。不过,我想知道是否有像位移一样的替代方法。 @Sim:对于MAX 的任意值,并非如此。您总是可以定义一个庞大的查找表,但由于缓存性能糟糕,这可能不会更快! @OliCharlesworth:谢谢。我只是好奇如果我的 MAX_NUMBER_VALUE 可以表示为 2^n,我将如何编写移位包装? @Sim:假设 2 的补码,那么你应该可以只做x &= (2*n-1); if (x >= n) x -= 2*n;【参考方案2】:
int_fast8_t translate(int_fast32_t value) 
  return sgn(value)*( (abs(value)+MAX)%(2*MAX+1)-MAX )

应该这样做,假设为 int_fast32_t 类型定义了模块化划分

已编辑以包括处理负数,但现在看起来有点混乱。有关 sgn(x) 的智能实现,请参阅this

【讨论】:

您确定要将输出范围设为闭合区间 [-MAX_NUMBER_VALUE, MAX_NUMBER_VALUE]?使用半开区间 [-MAX_NUMBER_VALUE, MAX_NUMBER_VALUE) 或 (-MAX_NUMBER_VALUE, MAX_NUMBER_VALUE] 会更自然 谢谢,但我认为这不会包含负数,比如 -101:(-101+100)%(2*100+1)-100 = -101 当然,抱歉。我应该注意之前关于“小心处理负数”的评论 要么我的数学是错误的,要么它仍然没有为负数换行:-101 => -1*(101+100)%(2*100+1)-100 = -100! :)【参考方案3】:

只要您的input + MAX_VALUE 小于相关整数类型的最大值,我认为您可以使用它,甚至不需要初始abs 检查:

return ((input + MAX_VALUE) % (MAX_VALUE * 2 + 1)) - MAX_VALUE;

【讨论】:

nrussell 之前曾建议过这个,但是这不会包含负数,比如 -101:(-101+100)%(100*2+1)-100 = -101

以上是关于基于最大值的换行/溢出数的算法的主要内容,如果未能解决你的问题,请参考以下文章

截止目前为止,我遇到的最难的一道算法题:计算相邻两个数的最大差值

截止目前为止,我遇到的最难的一道算法题:计算相邻两个数的最大差值

截止目前为止,我遇到的最难的一道算法题:计算相邻两个数的最大差值

用正则表达式,清除文章中多余的换行和空白字符

欧几里得算法和扩欧

awk,基于前一行开始范围的换行插入