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)+0x4000which 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
sqrtHLto 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.bis now the next 8 bits of the square root!xis 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 ofaas a 17.40 fixed-point number andbas an integer.- Keep track of the sign ! This cause a carry !
- Now we divide
aby2xagain, 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*bfroma- Note that this is a 16x16 multiply
- Finally, we divide our new
aby2x, getting 32 bits. No need to preserve a remainder. This quotient is the final 32 bits of the result.