开发者

Is this a clever or stupid way to do an integer divide function?

开发者 https://www.devze.com 2023-02-09 07:33 出处:网络
I\'m a Computer Science major, interested in how assembly languages handle a integer divide function. It seems that simply adding up to the numerator, while giving both the division and the mod, is wa

I'm a Computer Science major, interested in how assembly languages handle a integer divide function. It seems that simply adding up to the numerator, while giving both the division and the mod, is way too impractical, so I came up with another way to divide using bit shifting, subtracting, and 2 look up tables.

Basically, the function takes the denominator, and makes "blocks" based on the highest power of 2. So dividing by 15 makes binary blocks of 4, dividing by 5 makes binary blocks of 3, etc. Then generate the first 2^block-size multiple of the denominator. For each multiple, write the values AFTER the first block into the look up table, keyed by the value of the first block.

Example: Multiples of 5 in binary - block size 3 (octal)

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

So the actual procedure involves getting the first block, left bit-shifting over the first block, and subtracting the value that the blocks maps to. If the resulting number comes out to 0, then it's perfectly divisible, and if the value becomes negative, it's not.

If you add another enumeration look up table, where you map the values to a counter as they come in, you can calculate the result of the division!

Example: Multiples of 5 again

5 maps to 1  
2 maps to 2  
7 maps to 3  
4 开发者_JS百科maps to 4  
1 maps to 5  
6 maps to 6  
3 maps to 7  
0 maps to 8  

Then all that's left is mapping every block to the counter-table, and you have your answer.

There are a few problems with this method.

  1. If the answer isn't perfectly divisible, then the function returns back junk.
  2. For high Integer values, this won't work, because a 5 block size will get truncated at the end of a 32 bit or 64 bit integer.
  3. It's about 100 times slower than the standard division in C.
  4. If the denominator is a factor of the divisor, then your blocks must map to multiple values, and you need even more tables. This can be solved with prime factorization, but all the methods I've read about easy/quick prime factorization involve dividing, defeating the purpose of this.

So I have 2 questions: First, is there an algorithm similar to this out there already? I've looked around, and I can't seem to find any like it. Second, How do actual assembly languages handle Integer division?

Sorry if there are any formatting mistake, this is my first time posting to stack overflow.


Sorry i answer so late. Ok, first regarding the commenters of your question: they think you are trying to do what the assembly memonic DIV or IDIV achieves by using different instructions in assembly. To me it seems you want to know how the op-codes that are selected by DIV and IDIV achieve division in hardware. To my knowledge Intel uses the SRT algorithm (uses a lookup-table) and AMD uses the Goldschmidt algorithm. I think what you are doing is similar to SRT. You can take a look at both of them here:

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

0

精彩评论

暂无评论...
验证码 换一张
取 消