Using Floating Point to integer subroutines
I am having trouble using Microchips floating point routines, and I believe I'm just missing or misreading something simple. I don't actually want to do any math, but I am taking a float from a serial stream and want to display the value with 1 decimal point. I am hard coding an easy float into aint. I have used multiple online converters to verify that 50.0 = 0x42480000. I chose it because it is nice and round and does not use the parity bit for any of the bytes when I get to the point of going back to a serial line. I can't seem to get either ftoia or itofb to do what I thought they should do.
Code:
include "fp1832l.bas"
aint = $42480000
serout2 portc.6,newbaud,["a hex value = ", hex8 aint]
gosub ftoia
serout2 portc.6,newbaud,["after conversion, a hex value = ", hex8 aint]
bint = 10
serout2 portc.6,newbaud,["b hex value = ", hex8 bint]
gosub itofb 'convert to float
serout2 portc.6,newbaud,["after conversion, b hex value = ", hex8 bint]
For inta the hex value before is displayed correctly, $42480000, however the value after conversion is the exact same
For intb, the hex value is as expected, $0000000A, but after the conversion it is $20000000. the online calculators show $41200000 is what a 10 should look like as a float.
If there is an easier way to get what I need, I would appreciate it or just helping me see what I'm missing. Again, I don't necessarily need math. I just want to convert a single float into a couple of variables for each side of the decimal to display.
Thanks for the clarification
David
Re: Using Flaoting Point to integer subroutines
Hi,
This is new teritory for me but looking at the FPREADME.TXT it seems to me that you're basically using the wrong variables.
Quote:
itofa Convert integer aint to floating point aarg
itofb Convert integer bint to floating point barg
fpadd Perform floating point addition: aarg + barg
fpsub Perform floating point subtraction: aarg - barg
fpmul Perform floating point multiplication: aarg * barg
fpdiv Perform floating point division: aarg / barg
ftoia Convert floating point aarg to integer aint
The way I interpret this is that use ftoia you should load the floating point number into aarg (not aint, like you're doing) and retrieve the result from aint. For itofb, you should load the integer value to bint and retrieve the result from barg (not bint, like you're doing).
Could that be it?
/Henrik.
Re: Using Flaoting Point to integer subroutines
Along with what Henrik said ...
Quote:
Originally Posted by Luckyborg
I have used multiple online converters to verify that 50.0 = 0x42480000.
Most online convertors will use the IEEE floating point format. The format that is used in most PC languages.
But Microchip uses a different format. And 50 in Microchip's format is 0x84480000.
So if you are receiving IEEE formatted floats, you will not be able to convert them with the Microchip Floating Point routines without first converting to Microchip format.
Re: Using Flaoting Point to integer subroutines
I gave it a try, but aarg and barg are not declared. I loaded up the FP1832L.bas file to take a look and found aint and bint, and the comments say that aint is the Long access to AARG. My understanding is that any call on aint will overwrite itself with the new value and the original value of aint is lost.
I pretty much based my code on the what I found on melabs website http://melabs.com/resources/fp.htm
You had my hopes up though. Thanks for looking
David
Re: Using Flaoting Point to integer subroutines
Thanks Darrel, I didn't realize microchip had its own format. Any idea on how to convert the IEEE standard?
Re: Using Flaoting Point to integer subroutines
I found some C code that helped with the transition. When I get everything running I'll post it. I was able to translate the 42480000 to 84480000 but I'm still getting nothing out of the ftoia call. The value of aint is the same before and after. I looked through the include files and the best I can tell is aint should be the variable being changed.
Quote:
aint = S_RateL 'copy over
serout2 portc.6,newbaud,["hex value = ", hex8 aint]
gosub ftoia
serout2 portc.6,newbaud,["after conversion hex value = ", hex8 aint]
Re: Using Flaoting Point to integer subroutines
Thanks to you both, that was the information I needed. I went through the readme file and the FP1832L.bas file again and I still don't see where it says AARG starts at AARGB2, but you obviously know what your talking about because I have been able to make progress on my project now. Thanks again.
Re: Using Flaoting Point to integer subroutines
Hi,
In this case I certainly won't take any credit because right now I don't understand it either. I'm looking at the README and at the FP1832L.BAS and I don't see it.
I wonder if it's a byte order thing or something like that?
/Henrik.
Re: Using Flaoting Point to integer subroutines
Well, having never used the Floating Point routines before ... you still knew the value went in AARG instead of Aint ... that's worth something.
I guess it's easier when you know how it works.
A floating point value consists of 4 bytes (32-bits).
The highest byte is the exponent.
Looking at the list of variables in FP1832L.bas, the only way to put 4 bytes in a row with the exponent lining up with AEXP is to start at AARGB2 ($1d).
Code:
aint var long $1c ' Long access to AARG
AARGB3 var aint.byte0 ' $1c
AARGB2 var aint.byte1 ' $1d
AARGB1 var aint.byte2 ' $1e
AARGB0 var aint.byte3 ' $1f
AEXP var byte $20
Microchip saves RAM space by using the same memory for Floats and Integers.
But when you have an integer value, the LONG variable uses AARGB3-AARGB0 (aint).
I believe the routines were intended to be used by starting with integers, converting to floats, and doing the math from there.
They were never intended to accept previously encoded floating-point values, whether IEEE or Microchip format.
Hence that ability is not documented.
Undocumented features are way more fun than the documented ones. :)