PDA

View Full Version : Converting 32 bit Floating Point, and 48 and 64 bit Integer to string



pedja089
- 7th March 2015, 22:38
I need to upgrade old project. It's quit complicated...
Now it need to display data received via serial port. There is few data format which need to be displayed.

Most critical is 32bit Floating Point. There is no need for any other calculation, except converting it to ASCII string.
I have about 30K of code space, for implementing 32 bit FP to ASCII converter, and 64bit Integer do ASCII.

Does any have any idea where to start?

One other thing that crossed my mind is to create small program that convert data from X ram location to ASCII and store it in ram on Y location in some other programming language that support FP.
Program should start at predefined address and use predefined ram. So I can put data at right place, call some address and then get ASCII string back...
If i could change data formats I would, but I can't. It's fixed...

I forgot to say for FP I need -###.### format, without leading zeros, and only - in front if negative. Maybe it helps that range is +/-100 for FP. And full range for signed and unsigned integers...
I really doesn't understand why is so much data formats used on same device.

richard
- 7th March 2015, 23:31
you have not really explained what format the serial data input takes . can you provide a few examples of input data verses desired result

pedja089
- 7th March 2015, 23:46
I can try to explain. I get 4 bytes for FP.
Eg:
For temperature 23.75, I get 4 bytes $41,$BE,$00,$00
24.375=$41,$c3,$00,$00
etc...
And that values matches with results from this calculator:
http://www.h-schmidt.net/FloatConverter/IEEE754.html

richard
- 7th March 2015, 23:47
this may help esp post#7
http://www.picbasic.co.uk/forum/showthread.php?t=19074&highlight=floating

pedja089
- 7th March 2015, 23:54
Thanks!
I just take short look at that, and that should be exactly what I need. I'll give it a try and report back. Thank again.

pedja089
- 7th March 2015, 23:57
While writing first post, I was thinking that DT isn't around any more...
And here it is, his solution :)
Thanks

pedja089
- 8th March 2015, 11:03
I found this article
http://www.picbasic.co.uk/forum/content.php?r=153-N-Bit_MATH
That should be enough, to display 64 bit integer.

pedja089
- 8th March 2015, 14:19
I tested Darrels example with more numbers and something doesn't work...


include "fp1832l.bas"

;----[Variables]----------------------------------------------------------------
A VAR LONG
B VAR LONG
A_Float VAR LONG EXT : @A_Float = AARGB2 ;
B_Float VAR LONG EXT : @B_Float = BARGB2 ;
OutStr VAR BYTE[20]
;----[macro Converts IEEE to Microchip FP format]-------------------------------
ASM
IEEEtoMCHIP?NN macro Nin, Nout
MOVE?BB Nin, Nout
MOVE?BB Nin+1, Nout+1
MOVE?BB Nin+2, Nout+2
MOVE?TT Nin+3,7, Nin+2,7
MOVE?BA Nin+3
RLNCF WREG,W
MOVE?AB Nout+3
MOVE?TT Nin+2,7, Nout+3,0
endm
ENDASM

;----[Test IEEE to Microchip conversion]---------------------------------------
HSEROUT2 ["Value from IEEE calculator: 50" ,13,10]
A = $42480000 ; 50 - IEEE
GOSUB ShowConversion

HSEROUT2 ["Value from IEEE calculator: -25.62" ,13,10]
A = $C1CCF5C3 ; -25.62 - IEEE
GOSUB ShowConversion

HSEROUT2 ["Value from IEEE calculator: 23.75" ,13,10]
A = $41BE0000 ; 23.75 - IEEE
GOSUB ShowConversion

HSEROUT2 ["Value from IEEE calculator: 35.00" ,13,10]
A = $420C0000 ; 35.00 - IEEE
GOSUB ShowConversion

HSEROUT2 ["Value from IEEE calculator: 24.00" ,13,10]
A = $41C00000 ; 24.00 - IEEE
GOSUB ShowConversion

HSEROUT2 ["Value from IEEE calculator: 22.00" ,13,10]
A = $41B00000 ; 22.00 - IEEE
GOSUB ShowConversion

HSEROUT2 ["Value from IEEE calculator: 8.875" ,13,10]
A = $410E0000 ; 8.875 - IEEE
GOSUB ShowConversion

STOP

;----[Show conversion via HSEROUT]---------------------------------------------
ShowConversion:
HSEROUT2 ["IEEE = ",HEX8 A,13,10]
@ IEEEtoMCHIP?NN _A, _B
HSEROUT2 ["Mchip= ",HEX8 B,13,10]

A_Float = B
GOSUB FtoIA
HSEROUT2 ["Aint = ",SDEC Aint,13,10]
A = Aint

A_Float = B ; with 1 decimal place
Bint = 10
GOSUB ItoFB
GOSUB fpmul
GOSUB FtoIA
HSEROUT2 [" ",SDEC Aint/10,".",DEC1 ABS(Aint),13,10]

A_Float = B ; with 2 decimal places
Bint = 100
GOSUB ItoFB
GOSUB fpmul
GOSUB FtoIA
HSEROUT2 [" ",SDEC Aint/100,".",DEC2 ABS(Aint),13,10]

A_Float = B ; with 3 decimal places
Bint = 1000
GOSUB ItoFB
GOSUB fpmul
GOSUB FtoIA
HSEROUT2 [" ",SDEC Aint/1000,".",DEC3 ABS(Aint),13,10,13,10]

RETURN
Results:

Value from IEEE calculator: 50
IEEE = 42480000
Mchip= 84480000
Aint = 50
50.0
50.00
50.000

Value from IEEE calculator: -25.62
IEEE = C1CCF5C3
Mchip= 83CCF5C3
Aint = -25
-25.6
-25.62
-25.620

Value from IEEE calculator: 23.75
IEEE = 41BE0000
Mchip= 82BE0000
Aint = -11
-11.8
-11.87
-11.875

Value from IEEE calculator: 35.00
IEEE = 420C0000
Mchip= 840C0000
Aint = 35
35.0
35.00
35.000

Value from IEEE calculator: 24.00
IEEE = 41C00000
Mchip= 82C00000
Aint = -12
-12.0
-12.00
-12.000

Value from IEEE calculator: 22.00
IEEE = 41B00000
Mchip= 82B00000
Aint = -11
-11.0
-11.00
-11.000

Value from IEEE calculator: 8.875
IEEE = 410E0000
Mchip= 820E0000
Aint = 8
8.8
8.87
8.875

pedja089
- 8th March 2015, 16:20
As far as I can see, there is some problem with Darrel subroutine.
To get correct number in microchip format I used this code:

aint = 2375
Gosub itofa ' Convert int to float

bint = 100
Gosub itofb ' Convert int to float

Gosub fpdiv

Result is: $833E0000

And I can display correctly with this code:

A_Float = $833E0000 ; with 1 decimal place
Bint = 10
GOSUB ItoFB
GOSUB fpmul
GOSUB FtoIA
HSEROUT2 [" ",SDEC Aint/10,".",DEC1 ABS(Aint),13,10]

A_Float = B ; with 2 decimal places
Bint = 100
GOSUB ItoFB
GOSUB fpmul
GOSUB FtoIA
HSEROUT2 [" ",SDEC Aint/100,".",DEC2 ABS(Aint),13,10]

A_Float = B ; with 3 decimal places
Bint = 1000
GOSUB ItoFB
GOSUB fpmul
GOSUB FtoIA
HSEROUT2 [" ",SDEC Aint/1000,".",DEC3 ABS(Aint),13,10,13,10]

Output is:
23.7
23.74
23.749
That is fine...

But when I try to convert $41BE0000 with Darrel's routine result is
IEEE = 41BE0000
Mchip= 82BE0000

pedja089
- 8th March 2015, 19:09
I think that I solved this...
From include file FP32.A18:

; 32 bit floating point representation

; EXPONENT 8 bit biased exponent

; It is important to note that the use of biased exponents produces
; a unique representation of a floating point 0, given by
; EXP = HIGHBYTE = MIDBYTE = LOWBYTE = 0x00, with 0 being
; the only number with EXP = 0.

; HIGHBYTE 8 bit most significant byte of fraction in sign-magnitude representation,
; with SIGN = MSB, implicit MSB = 1 and radix point to the right of MSB

; MIDBYTE 8 bit middle significant byte of sign-magnitude fraction

; LOWBYTE 8 bit least significant byte of sign-magnitude fraction

; EXPONENT HIGHBYTE MIDBYTE LOWBYTE

; xxxxxxxx S.xxxxxxx xxxxxxxx xxxxxxxx

; |
; RADIX
; POINT
IeeFormat:
http://www.h-schmidt.net/FloatConverter/IEEE754.html
As you can see in IEE format, only 7 bit of exponent is in first byte, so bit 23 should be shifted to first bit of byte3, when shifting to right exponent.
Here is binary for 23.75:

IEE 41BE0000 = 01000001 10111110 00000000 00000000
MCHIP 833E0000 = 10000011 00111110 00000000 00000000
Darel 82BE0000 = 10000010 10111110 00000000 00000000
As you can see Darrel's code set sign instead of first bit of exponent.
Here is my code, done in PBP

MyIEEEtoMCHIP:
B.BYTE0=A.BYTE0
B.BYTE1=A.BYTE1
B.BYTE2=A.BYTE2 : B.23=A.31 'SIGN
B.BYTE3=A.BYTE3<<1 : B.24=A.23
RETURN
A-IEEE
B-Microchip

I'll try to fix Darrel's macro.

pedja089
- 8th March 2015, 19:26
I fixed bug in Darrel's macro:

ASM
IEEEtoMCHIP?NN macro Nin, Nout
MOVE?BB Nin, Nout
MOVE?BB Nin+1, Nout+1
MOVE?BB Nin+2, Nout+2
;MOVE?TT Nin+3,7, Nin+2,7 ;<<<<<<<<here he is setting bit in input byte, not output byte
MOVE?TT Nin+3,7, Nout+2,7 ;<<<<<<<<Corrected
MOVE?BA Nin+3
RLNCF WREG,W
MOVE?AB Nout+3
MOVE?TT Nin+2,7, Nout+3,0
endm
ENDASM