Reputation: 14348
I have recently learned that for an m-bit x n-bit multiplication (producing an (m+n)-bit product), min(m,n)
least-significant bits of the result are always the same whether the multiplication is unsigned or signed.
For an m-bit / n-bit division (producing an m-bit quotient and a n-bit remainder), are there any bits which are always the same for both an unsigned and a signed division, or (for some inputs) do the two division methods produce completely different results?
Upvotes: 1
Views: 520
Reputation: 76567
If any operand has the MSB set (i.e. is negative), unsigned and signed division are markedly different.
If the MSB in both operands is zero (i.e. both numbers are positive), the result will be the same.
When using unsigned division all bits in the operands are interpreted as unsigned, i.e. negative numbers are interpreted as (very) large integers.
Results for div
:
mov eax, 1
xor edx, edx
mov ecx, -1
div ecx ; -> EAX = 0 because the -1 is interpreted as a large positive number
; -> EDX = 1
mov eax, -1
xor edx, edx
mov ecx, 2
div ecx ; -> EAX = $7FFFFFFF because div 2 shifts bits right by 1.
; -> EDX = 1
When using signed division the operands are first transformed to absolute numbers and then the signs of the operands are reapplied to the result of the division.
Results for idiv
:
mov eax, 1
xor edx, edx ; XOR because EAX is positive
mov ecx, -1
idiv ecx ; -> EAX = -1 because 1 / -1 = -1
; -> EDX = 0
mov eax, -1
cdq ; CDQ because EAX is negative
mov ecx, 2
idiv ecx ; -> EAX = 0 because 1 shr 1 = 0 and -0 is still 0
; -> EDX = -1
In some processors div
(with all positive operands) will be a cycle faster than idiv
because it has to do less 'thinking'. However given the fact that division is a horribly slow operation anyway, this will hardly matter.
Upvotes: 3
Reputation: 71536
Did you not learn from the prior question one how to do this? Back to grade school math, long division (thats how old/slow (many clocks) division works anyway).
Lets take the bit pattern 0b10101010 / 0b101, which is either unsigned 0xAA / 5 or signed -0x56 / -3. I had to cheat and use my calculator. Anyway the easy one first
-----------
101 ) 10101010
100010
-----------
101 ) 10101010
101
===
00101
101
===
00
so the result is 0x22
But for the signed division to get the right answer we need to do unsigned which is how you would do it by hand in grade school, then apply the sign later so we are not dividing 0b101 into 0b10101010 we are instead dividing 0b11 into 0b1010110
11100
---------
11 ) 1010110
11
===
100
11
===
11
11
==
010
So the answer is 0x1C remainder 0x2 because both were negative the result is positive.
Similar to add/subtract and signed and unsigned multiply, you negate or not going in and negate or not something coming out. Division is not like multiply where it is just the same number added over and over again after being shifted. You start from the left not the right as well so I just cant see how it would generate any kind of common pattern between them. Above demonstrates that but also demonstrates that if you negate one you get a lot of common bits up front, that is probably dumb luck.
I am not going to attempt to divide the bit variables abc into def unlike addition/subtract and multiply it doesnt work like that which is why some percentage of processors dont have multiply or divide or some have multiply but not divide, you can make the multiply faster by using a lot of logic, the divide perhaps as well, that or a lot of clocks.
Maybe look at Hackers Delight to see division shortcuts and from that maybe a pattern will emerge that makes some percentage of the bits the same but I doubt it. You have to get the actual binary operand going into the divide logic and probably the upper bits in the numerator to be the same signed or unsigned, but that means they are two totally different numbers. As demonstrated above if you take the same bit patterns which have different signed representations and you feed those same bit patterns into unsigned or signed division you get different bit patterns in the numerator and/or denominator and thus a different result, no patterns expected to match. If both numbers are positive then both should give the same result sure.
Upvotes: 1