Shop OBEX P1 Docs P2 Docs Learn Events
Float32 Question — Parallax Forums

Float32 Question

parskoparsko Posts: 501
edited 2012-09-25 10:49 in Propeller 1
Hi all,

I would like to work with Float32. My plan is to copy certain routines into my own assy cog and call the appropriate function from within my own assy cog (I only need FMul and FDiv).

What do these routines use for inputs, numerically?

Are they floating point numbers IEEE-754 standard or do they use 16.16 nomenclature?

The methods for Divide and Multiply in PASM use (what I'm calling) the 16.16 nomenclature. The manual calls for IEEE-754 for floating point stuff, but I can't confirm (yet, until I start playing with it) that FLOAT32 uses it as well. I'm assuming IEEE-754 is the answer...

Thanks,

-Parsko

Comments

  • SRLMSRLM Posts: 5,045
    edited 2012-09-24 15:59
    The routines use 32 bit floating point numbers as input. IIRC, the numbers are called "a" and "b" or some variant there of (fnumA and fnumB). You'll also need to copy along a number of support routines such as Pack, Unpack, Frac, and so on. Also, don't forget the long variables at the end.

    Basically, you'll need to go through the listings and see what each function calls and what is needed. But, once you do that it's easy to use. Here's a little PID routine I wrote that can be embedded in the code:
    _PID                    'Read the PID values from hub memory, starting with the Address in FNumA
    						rdlong	t1, fnumA
    						rdlong	fInput, t1
    						
    						add		fnumA, #4
    						rdlong	fOutput_addr, fnumA
    						
    						add		fnumA, #4
    						rdlong	t1, fnumA
    						rdlong	fSetpoint, t1
    						
    						add		fnumA, #4
    						mov		fITerm_addr, fnumA
    						rdlong	fITerm, fnumA
    						
    						add		fnumA, #4
    						mov		flastInput_addr, fnumA
    						rdlong  flastInput, fnumA						
    						
    						add		fnumA, #4
    						rdlong  fkp, fnumA
    						
    						add		fnumA, #4
    						rdlong  fki, fnumA
    						
    						add		fnumA, #4
    						rdlong  fkd, fnumA
    						
    						add		fnumA, #4
    						rdlong  foutMin, fnumA
    						
    						add		fnumA, #4
    						rdlong  foutMax, fnumA
    						
    						add		fnumA, #4
    						rdlong  finAuto, fnumA
    						
    						add		fnumA, #4
    						rdlong  fcontrollerDirection, fnumA
    
    				'TODO: what about the extra variables that I don't use (controlledr direction, etc.) Are those influencing the data here?
    
    						'double error = Setpoint - Input
    						mov		fnumA, fSetpoint
    						mov		fnumB, fInput
    						call	#_FSub
    						
    						mov		ferror, fnumA
    						
    						'ITerm += ki * error
    						mov		fnumB, fki
    						call	#_FMul
    						mov		fnumB, fITerm
    						call	#_FAdd
    						'fnumA now has ITerm
    						
    						'if(ITerm > outMax) ITerm= outMax;
    						mov		fnumB, foutMax
    						call	#_FLimitMax
    						'else if(ITerm < outMin) ITerm= outMin;
    						mov		fnumB, foutMin
    						call	#_FLimitMin
    						
    						mov		fITerm, fnumA
    						
    						wrlong	fITerm, fITerm_addr 'Store value for next time
    						
    						
    						
    						'double dInput = (Input - lastInput);
    						mov		fnumA, fInput
    						mov		fnumB, flastInput
    						call	#_FSub		
    
    						'/*Compute PID Output*/
    						'Output = kp * error + ITerm- kd * dInput;
    						
    
    						'kd * dInput
    						mov		fnumB, fkd
    						call	#_FMul
    
    						'ITerm - (fkd*fdInput == fnumA)						
    						mov		fnumB, fnumA
    						mov		fnumA, fIterm
    						call	#_FSub
    						
    						mov		fOutput, fnumA
    						
    						'kp * error
    						mov		fnumA, fkp
    						mov		fnumB, ferror
    						call	#_FMul
    '						
    						'Calculate proportional based on setpoint
    '						mov		fnumA, fkp
    '						mov		fnumB, fSetpoint
    '						call	#_FMul
    						
    						'(kp * error == fnumA) + (ITerm - (kf*dInput) == fOutput)
    						mov		fnumB, fOutput
    						call	#_FAdd
    						
    						'if(Output > outMax) Output = outMax;
    						mov		fnumB, foutMax
    						call	#_FLimitMax
    						
    						'else if(Output < outMin) Output = outMin;
    						mov		fnumB, foutMin
    						call	#_FLimitMin
    
    						'/*Remember some variables for next time*/
    						'lastInput = Input;
    						wrlong	fInput, flastInput_addr
    						'lastTime = now;
    						
    						wrlong	fnumA, fOutput_addr
    
    
    _PID_ret                ret
    
    

    You can see how easy it is to call the F32 commands from the code. Which brings me to another point: IIRC, F32 is the improved version (faster, smaller) of Float32. You may want to look into that.

    Also IIRC, the support routines took about 180 longs.
  • Heater.Heater. Posts: 21,230
    edited 2012-09-24 17:48
    Are they floating point numbers IEEE-754 standard.
    You might find the floating point routimes in the F32 obect by Lonesock smaller and/or faster.

    Note that although Spin does not support floating point opereations you can define floating point constants and use floating point literals:

    "A := 4.3424" will result in the correct floating point represenation being stored in A in IEE format.
  • parskoparsko Posts: 501
    edited 2012-09-25 04:49
    Cool, thanks for the clarification guys! Just what I needed. Time to play...

    -Parsko
  • parskoparsko Posts: 501
    edited 2012-09-25 07:53
    Does anyone know what "{Float immediate}" means? I'm assuming that I can input a non-floating point number and get out a floating point answer. This is used in Float32, but not F32.

    This is the syntax that this is pulled from, it's the FMul routine in Float32.
    '
    ' _FMul fnumA = fnumA * fNumB
    ' _FMulI fnumA = fnumA * {Float immediate}
    ' changes: fnumA, flagA, expA, manA, fnumB, flagB, expB, manB, t1, t2
    '

    To me, this implies that FnumA is a floating point number, and FnumB is an integer (not floating). Can anyone confirm?

    Thanks,

    -Parsko
  • Mike GreenMike Green Posts: 23,101
    edited 2012-09-25 10:07
    Nope. _FMul takes two floating point numbers (fNumA and fNumB) and multiplies them to produce a floating point result in fNumA. "Immediate" usually refers to a value that follows the call (immediately) in the code. The routine uses the return address as the address of the value to be used and increments the return address by an appropriate amount so the call returns after the value. Look at the _Cos routine for examples of this usage.
  • parskoparsko Posts: 501
    edited 2012-09-25 10:49
    AAAHHHH, okay! I remember, back when I was doing this frequently before, something like that. After perusing the assy code for both Float32 and F32, I see roughly what you are talking about. I remember that trick loosely, not that I can try to implement it today without further research.

    I seem to be getting it. I need to float my values first before sending them to the routines, that got me for the past couple hours.

    Thanks Mike!

    -Parsko
Sign In or Register to comment.