Float32Lib (Sqr and Pow issue)
Paul K.
Posts: 150
I'm working on some IK equations and its coming along pretty good.·
I came across a little issue with Square Root and Power Pubs.
I noticed in the assembly that If these equall 0 then they are NAN numbers.·
Actually they should be zero.· I did a search to see if someone else has had this issue but didnt find anything.·
The way I came across it is when my variable is· a zero I get the the error value.
I am not the best at assembly language but it seems the first few lines need to be tweeked to allow zero to just equal zero.
So I instead included this in the Pub parts of SQR and POW
PUB Pow(a, b)
· If a == 0
··· return 0
· 'return sendCmd(PowCmd + @a)
· command := PowCmd + @a
· repeat while command
· return cmdReturn
PUB FSqr(a)
· If a == 0
··· return 0
· 'return sendCmd(FSqrCmd + @a)
· command := FSqrCmd + @a
· repeat while command
· return cmdReturn·
It works fine this way.
I tried to figure this out but I not sure what the fix is.· I assume it has something to to with the lines I turned red below.
'
' _FSqr··· fnumA = sqrt(fnumA)
' changes: fnumA, flagA, expA, manA, t1, t2, t3, t4, t5
'
_FSqr·················· call··· #_Unpack················ ' unpack floating point value
········· if_nc········ mov···· fnumA, #0··············· ' set initial result to zero
······· '· if_c_or_z···· jmp···· #_FSqr_ret·············· ' check for NaN or zero
······· '··············· test··· flagA, #signFlag wz····· ' check for negative
······· '· if_nz········ mov···· fnumA, NaN·············· ' yes, then return NaN······················
······· '· if_nz········ jmp···· #_FSqr_ret
·········
······················· test··· expA, #1 wz············ ' if even exponent, shift mantissa
········· if_z········· shr···· manA, #1
······················· sar···· expA, #1··············· ' get exponent of root
······················· mov···· t1, Bit30·············· ' set root value to $4000_0000··············· '
······················· mov···· t2, #31················ ' get loop counter
:sqrt·················· or····· fnumA, t1·············· ' blend partial root into result
······················· mov···· t3, #32················ ' loop counter for multiply
······················· mov···· t4, #0
······················· mov···· t5, fnumA
······················· shr···· t5, #1 wc·············· ' get initial multiplier bit
·······················
:multiply if_c········· add···· t4, fnumA wc··········· ' 32x32 bit multiply
······················· rcr···· t4, #1 wc
······················· rcr···· t5, #1 wc
······················· djnz··· t3, #:multiply
······················· cmps··· manA, t4 wc············ ' if too large remove partial root
········· if_c········· xor···· fnumA, t1
······················· shr···· t1, #1················· ' shift partial root
······················· djnz··· t2, #:sqrt············· ' continue for all bits
·······················
······················· mov···· manA, fnumA············ ' store new mantissa value and exit
······················· shr···· manA, #1
······················· call··· #_Pack
_FSqr_ret·············· ret
Any explaination would be great.
And the Pow asm code I have no clue at all.
Thanks
Paul
Post Edited (Paul K.) : 10/8/2008 11:44:28 PM GMT
I came across a little issue with Square Root and Power Pubs.
I noticed in the assembly that If these equall 0 then they are NAN numbers.·
Actually they should be zero.· I did a search to see if someone else has had this issue but didnt find anything.·
The way I came across it is when my variable is· a zero I get the the error value.
I am not the best at assembly language but it seems the first few lines need to be tweeked to allow zero to just equal zero.
So I instead included this in the Pub parts of SQR and POW
PUB Pow(a, b)
· If a == 0
··· return 0
· 'return sendCmd(PowCmd + @a)
· command := PowCmd + @a
· repeat while command
· return cmdReturn
PUB FSqr(a)
· If a == 0
··· return 0
· 'return sendCmd(FSqrCmd + @a)
· command := FSqrCmd + @a
· repeat while command
· return cmdReturn·
It works fine this way.
I tried to figure this out but I not sure what the fix is.· I assume it has something to to with the lines I turned red below.
'
' _FSqr··· fnumA = sqrt(fnumA)
' changes: fnumA, flagA, expA, manA, t1, t2, t3, t4, t5
'
_FSqr·················· call··· #_Unpack················ ' unpack floating point value
········· if_nc········ mov···· fnumA, #0··············· ' set initial result to zero
······· '· if_c_or_z···· jmp···· #_FSqr_ret·············· ' check for NaN or zero
······· '··············· test··· flagA, #signFlag wz····· ' check for negative
······· '· if_nz········ mov···· fnumA, NaN·············· ' yes, then return NaN······················
······· '· if_nz········ jmp···· #_FSqr_ret
·········
······················· test··· expA, #1 wz············ ' if even exponent, shift mantissa
········· if_z········· shr···· manA, #1
······················· sar···· expA, #1··············· ' get exponent of root
······················· mov···· t1, Bit30·············· ' set root value to $4000_0000··············· '
······················· mov···· t2, #31················ ' get loop counter
:sqrt·················· or····· fnumA, t1·············· ' blend partial root into result
······················· mov···· t3, #32················ ' loop counter for multiply
······················· mov···· t4, #0
······················· mov···· t5, fnumA
······················· shr···· t5, #1 wc·············· ' get initial multiplier bit
·······················
:multiply if_c········· add···· t4, fnumA wc··········· ' 32x32 bit multiply
······················· rcr···· t4, #1 wc
······················· rcr···· t5, #1 wc
······················· djnz··· t3, #:multiply
······················· cmps··· manA, t4 wc············ ' if too large remove partial root
········· if_c········· xor···· fnumA, t1
······················· shr···· t1, #1················· ' shift partial root
······················· djnz··· t2, #:sqrt············· ' continue for all bits
·······················
······················· mov···· manA, fnumA············ ' store new mantissa value and exit
······················· shr···· manA, #1
······················· call··· #_Pack
_FSqr_ret·············· ret
Any explaination would be great.
And the Pow asm code I have no clue at all.
Thanks
Paul
Post Edited (Paul K.) : 10/8/2008 11:44:28 PM GMT
Comments
-Phil
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
'Still some PropSTICK Kit bare PCBs left!
This is a snipet of code.
B := f.fsqr(f.fadd((f.pow(PX,2.0)),(f.pow(PY,2.0)))) Pythagorean theorm.
If PX or PY is a zero it dosent return a real number for B instead it returns a NAN value.
The same if you try to square root 0 it returns a NAN. Where it should be 0
I know that if one of these is a zero then you really dont have a triangle instead just a line. But it gives me the length of a point from the origin to X,0 or 0,X.
Paul
I think it should be:
If a == float(0)
return float(0)