【问题标题】:Bitshifts to obtain remainder移位以获得余数
【发布时间】:2012-11-25 04:08:56
【问题描述】:

我想知道如何通过仅使用位移或按位运算符将一个整数除以另一个整数(均为正数)来获得余数。不应使用 / 运算符或 % 运算符。

例如,当除数的形式为2^k 时,为了获得余数,以下操作产生余数。

m = Remainder

n = The number

d = The divisor

m = n & ( d - 1 )

但是,此方法仅在 d 的形式为 2^k 时才有效。我想知道2 的非权力的类似方法。我目前正在处理来自programming challenges 的问题,并希望采用这种方法来减少程序执行时间

【问题讨论】:

  • 位表示仅以 base-2 表示这一事实不是限制吗?考虑值 43/7 - 该值实际上是 6.142857...。对于基数大于 2 的值,您考虑过什么通用方法?
  • 没有通用的方法。但是,如果您知道除数,则可以用乘法和一些移位和加法/减法替换除法。询问任何有能力的 C 编译器,它会给你任何编译时间常数的神奇值。
  • 除非答案只涉及 1 个 bitshift 语句,否则我敢打赌你不会打败 javas mod 运算符。
  • @rambocoder 如果您对魔法乘数和移位距离进行硬编码,它应该在大多数 CPU 上胜过除法运算。但这当然仅限于您在编译时知道的除数。
  • 我找到了this link。仅凭它并没有资格获得答案,但它可能足以让您上路。

标签: java bit-manipulation number-theory


【解决方案1】:

任何不使用运算符% 的答案都将是一个效率较低的答案,但是,如果您绝对不能使用运算符,那么一种解决方案是使用循环从 n 中重复减去 d:

m = n;
while (m >= d)
{
  m -= d;
}

假设你的整数是 32 位的,那么你可以考虑一个优化的版本,我们从 n 中删除 d 的倍数:

m = n;
for (i = 31; i >= 0; i--)
{
  di = d << i;
  if (di > 0 && m >= di) m -= di;
}

此示例假定整数已签名并监视溢出,即di &gt; 0 的测试。

【讨论】:

  • 不幸的是,溢出的移位不一定会导致负数,即使您假设一台正常的 2s-complement 机器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-31
  • 2023-02-18
  • 1970-01-01
  • 1970-01-01
  • 2018-05-01
  • 2016-05-11
相关资源
最近更新 更多