【问题标题】: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做一个模数...

标签: c++ c algorithm


【解决方案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
猜你喜欢
  • 2015-05-25
  • 1970-01-01
  • 1970-01-01
  • 2023-02-03
  • 1970-01-01
  • 2017-08-12
  • 1970-01-01
  • 2020-03-29
  • 2015-11-14
相关资源
最近更新 更多