Oh geez, sorry misk, I missed this question.
Basically, it just uses the divide first to reduce the size of the numbers, then does the multiply. This helps keep it within the 65535 limit. (a / 3 * 5) is the same as (a * 5 / 3)
Since the largest result of (60,000 * 5 / 3) = 100,000 which is 0001:86A0, you really only have to worry about 1 bit above the 65535 limit. In this case it worked out nicely that the largest number you can multiply by 5 and still be within 65535 is 13107. Anything larger, and you just add an extra bit, then do the multiply like normal.
After dividing the original number:
ResLow = a / 3
If you subtract 13107 from it, and it becomes negative, then the twos compliment value of the negative number will have bit 15 as a 1. This means that the number is not large enough to cause an overflow. So, the next statement just isolates that bit15 and inverts it with an xor operator (^ 1). This now becomes the low bit of the high word.
ResHigh = ((ResLow - 13107) >> 15) ^ 1
It kind of like saying.. If (a / 3 * 5) > 65535 then ResHigh = 1.
If you could actually do that in PBP, it would be much easier.
Now that the High word is complete, you can just do the multiply times 5 and just let it overflow (if it does).
Finally, in the first divide by 3, there is usually something left over. It's always either a 0, 1, or 2 (a // 3) the modulas of 3.
To get the decimal of that modulas, you would normally divide that number by the original divisor. Therefore, 0/3 = 0, 1/3 = .3333, 2/3 = .6666. But in this case, it also needs to be multiplied by 5. 0*5=0, .333*5=1.6666, .6666*5=3.3333.
Then the resulting integer is added to the original result. In the above formula, I rounded it off to 1.5 or 15/10 since you get the same integer value. Now, 0*15/10=0, 1*15/10=1 and 2*15/10=3 in integer results.
ResLow = ResLow * 5 + (a // 3 * 15 / 10)
And Ummm, or Ohhh, duhh, oh Crap.
Now I can see that by not considering the remainder when getting the High bit, there is 1 number that the formula doesn't work for. 39321 the result ends up as 0001:FFFF instead of 0000:FFFF. Not good.
Thanks misk! That would have probably driven Tomasm crazy.
See next Post.
Bookmarks