这是一种做整数除法函数的聪明或愚蠢的方法吗?

时间:2011-02-08 00:51:13

标签: algorithm division integer-division

我是计算机科学专业,对汇编语言如何处理整数除法函数感兴趣。似乎简单地加上分子,同时给出除法和mod,这太不切实际了,所以我提出了另一种方法来使用位移,减法和2个查找表进行划分。

基本上,函数采用分母,并根据2的最大功率生成“块”。因此除以15使得二进制块为4,除以5使二进制块为3,等等。然后生成前2 ^分母大小的分母。对于每个倍数,将第一个块的值 AFTER 写入查找表,并以第一个块的值为键。

示例:二进制5的倍数 - 块大小3(八进制)

000 000 **101** - 5 maps to 0    
000 001 **010** - 2 maps to 1  
000 001 **111** - 7 maps to 1  
000 010 **100** - 4 maps to 2  
000 011 **001** - 1 maps to 3  
000 011 **110** - 6 maps to 3  
000 100 **011** - 3 maps to 4  
000 101 **000** - 0 maps to 5

因此,实际的过程包括获取第一个块,在第一个块上左移位,并减去块映射到的值。如果结果数字变为0,则它​​完全可以被整除,如果该值变为负数,则不是。

如果添加另一个枚举查找表,将值映射到计数器,您可以计算除法的结果!

示例:再次为5的倍数

5 maps to 1  
2 maps to 2  
7 maps to 3  
4 maps to 4  
1 maps to 5  
6 maps to 6  
3 maps to 7  
0 maps to 8  

然后剩下的就是将每个块映射到计数器表,你得到答案 这种方法存在一些问题。

  1. 如果答案不能完全整除,那么该函数会返回垃圾邮件。
  2. 对于高整数值,这将不起作用,因为5块大小将在32位或64位整数的末尾被截断。
  3. 它比C中的标准分部慢100倍。
  4. 如果分母是除数的一个因子,那么您的块必须映射到多个值,甚至还需要更多表。这可以通过素数因子分解来解决,但我读过的关于简单/快速素数因子分解的所有方法都涉及划分,从而破坏了这个目的。
  5. 所以我有两个问题:首先,是否有类似于此的算法?我环顾四周,似乎找不到任何类似的东西。其次,实际汇编语言如何处理整数除法?

    对不起,如果有任何格式错误,这是我第一次发帖到堆栈溢出。

1 个答案:

答案 0 :(得分:1)

抱歉,我这么晚回答。好的,首先关于你问题的评论者:他们认为你正试图通过在程序集中使用不同的指令来完成汇编memonic DIV或IDIV所达到的目的。对我来说,似乎你想知道DIV和IDIV选择的操作码如何实现硬件中的划分。据我所知,英特尔使用SRT算法(使用查找表),AMD使用Goldschmidt算法。我认为你所做的与SRT类似。您可以在这里查看它们:

  

http://en.wikipedia.org/wiki/Division_%28digital%29