简体   繁体   English

使用移位运算符除以任意数字

[英]Dividing by arbitrary numbers using shifting operators

How can you divide a number n for example by 24 using shifting operators and additions? 如何使用移位运算符和加法将数字n除以例如24

( n % 24 == 0 ) n % 24 == 0

The pencil-and-paper algorithm for the division uses only "shifts" (base 10 shifts) and subtractions. 用于除法的纸笔算法仅使用“班次”(以10为基础班次)和减法。 You can do exactly the same thing in base 2. 您可以在base 2中执行完全相同的操作。

Sorry I can't find a link for the algorithm, but you should have learnt it as a child. 抱歉,我找不到该算法的链接,但您应该从小就学习它。

EDIT: actually since additions are cheap, you don't have to try to extract the correct digits one by one, so you can simplify the algorithm a bit... 编辑:实际上,由于加法很便宜,因此您不必尝试一一提取正确的数字,因此可以稍微简化算法...

Assuming positive dividend and divisor... 假设正股利和除数...

Take the power of two immediately larger than the divisor (here, 32). 取比除数(此处为32)大的二的幂。

It is easy to divide your number by this power of two. 将您的数字除以二的幂很容易。 Say the division produces k1 . 说除法产生k1 Subtract k1*24 from the number (call the rest r1 ) and iterate... 从数字中减去k1*24 (称为余数r1 )并迭代...

When you have obtained k1 , k2 , ... kn numbers and the rest rn no longer contains 32, do a last check to see if rn contains 24. 当获得k1k2 ,... kn个数并且其余rn不再包含32时,请最后检查rn包含24。

The result of the division is k1+k2+...+kn (+1 if 24 fits in rn) . 除法的结果是k1+k2+...+kn (+1 if 24 fits in rn)

This works by first finding the highest bit of the result, and then working back. 通过首先找到结果的最高位,然后再进行工作,可以工作。

int div24(int value) {
  // Find the smallest value of n such that (24<<n) > value
  int tmp = 24;
  for (int n = 0; tmp < value; ++n)
    tmp <<= 1;
  // Now start working backwards to find bits of the result. This is O(i).
  int result = 0;
  while(value != 0) {
    tmp >>= 1;
    result <<= 1;
    if (value > tmp) { // Found one bit.
       value -= tmp; // Subtract (24<<i)
       result++;
    }
  }
  return result;
}

Example: 例:

Value = 120 :  n = 2
Step 0: tmp = 96, result = 0, value = 24, result = 1
Step 1: tmp = 48, result = 2
Step 2: tmp = 24, result = 4, value = 0, result = 5
int
div24(int value) {
   int result = 0;
   while (value >= 24) {       
      int accum = 24;
      int tmp = 1;    
      while (accum + accum <= value) {
         accum += accum;
         tmp += tmp;
      }
      value -= accum;     
      result += tmp;
   }   
   return result;
}

尽管毫无疑问,对于24来说,这是一个聪明的技巧,但使用移位运算符(和/或减法)仅对2的幂才有意义。即使那样,它也更可能使读者感到困惑,而不是用现代的方法生成更有效的代码。编译器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM