xsqrt - Zeda/z80float GitHub Wiki
The algorithm used for xsqrt
is as follows:
- If the input is negative, return
NaN
. - If the input is
0
,NaN
, orinf
, then return the input as the output.
Otherwise:
- The new exponent will be half the input.
- The exponent has a bias of 0x4000. We basically need to do
((exp-0x4000)>>1)+0x4000
which is(exp+0x4000)>>1
. Since we have a positive float, we don't have to worry about the sign bit messing stuff up. - If the shift does not set the carry flag , then we shift the mantissa right. We do this so that we don't need to multiply the final result by
sqrt(1/2)
.
- The exponent has a bias of 0x4000. We basically need to do
The actual algorithm is a convoluted implementation of Newton's Method. If you want a proof of the algorithm, just let me know.
- Take the top 16 bits and use
sqrtHL
to find the square root (x
), with remainder (a
). (ex. sqrt(19) returns 4 with remainder 3, since 19=4*4+3).- We now have the first 8 bits of the square root!
- The bottom 48 bits of the input are also the bottom 48 bits of the "remainder".
- Next, we divide
a
(the remainder), by2x
, stopping at 8 bits and keeping the remainder. We will call the quotient,b
.b
is now the next 8 bits of the square root!x
is now 16 bit- Our remainder for the new division is our new
a
- From our new
a
, subtractb*b
. Remember, at this point, you can think ofa
as a 17.40 fixed-point number andb
as an integer.- Keep track of the sign ! This cause a carry !
- Now we divide
a
by2x
again, but this time to 16 bits. The quotient is our newb
- The quotient is now the next 16 bits of the square root. The remainder is our new
a
.
- The quotient is now the next 16 bits of the square root. The remainder is our new
- subtract
b*b
froma
- Note that this is a 16x16 multiply
- Finally, we divide our new
a
by2x
, getting 32 bits. No need to preserve a remainder. This quotient is the final 32 bits of the result.