[solved] Math Guru III How to normalize floating point ?
-
- Posts: 8586
- Joined: May 28, 2005 3:28
- Contact:
[solved] Math Guru III How to normalize floating point ?
Hello math guru you can help and teach me if you like :-)
Today I got for my 8-bit retro computer project an AM9511 8-bit coprocessor. am9511_datasheet.pdf
Currently I write an assembler and BASIC compiler (a subset of FreeBASIC) for the Motorola 6800 / 6803 MCU.
(I wrote an MC 6803 emulator in FreeBASIC also: http://www.freebasic.net/forum/viewtopi ... =8&t=22944)
The problem I don't know how to get from ASCII string like "const PI = 3.141592654" the 4 bytes for the AM9511 coprocessor.
Here are the binary floating point format of the AM9511 it must be normailzed so bit 23 is allways 1:
What I need is a good commented pair of function like:
function StringToLong(value as string) as long
function LongToString(value as long) as string
If I know how it works I have to write it as 8-bit assembler code.
Thank you
Joshy
Today I got for my 8-bit retro computer project an AM9511 8-bit coprocessor. am9511_datasheet.pdf
Currently I write an assembler and BASIC compiler (a subset of FreeBASIC) for the Motorola 6800 / 6803 MCU.
(I wrote an MC 6803 emulator in FreeBASIC also: http://www.freebasic.net/forum/viewtopi ... =8&t=22944)
The problem I don't know how to get from ASCII string like "const PI = 3.141592654" the 4 bytes for the AM9511 coprocessor.
Here are the binary floating point format of the AM9511 it must be normailzed so bit 23 is allways 1:
What I need is a good commented pair of function like:
function StringToLong(value as string) as long
function LongToString(value as long) as string
If I know how it works I have to write it as 8-bit assembler code.
Thank you
Joshy
Last edited by D.J.Peters on Oct 03, 2017 8:14, edited 3 times in total.
Re: Math Guru III How to normalize floating point ?
No code, just some hints:
To me it looks like this type is a kind nonstandard SINGLE. (one bit more mantissa, one bit less exponent).
So as intermediate type, use double (single might not have enough precision), and create double2AM951 and vice versa procedures. Then you can create the functions you want with the relevant double<->string conversion routines and these.
Get the individual parts (mantisse,exponent,sign) from the double, round them properly and put them in the 32-bits value. Watch out for special encoding schemes (like not storing the first bit of the mantissa, or having a biassed exponent, which means that an exponent x (e.g. an exponent -127<x<127 is stored as x+128)
To me it looks like this type is a kind nonstandard SINGLE. (one bit more mantissa, one bit less exponent).
So as intermediate type, use double (single might not have enough precision), and create double2AM951 and vice versa procedures. Then you can create the functions you want with the relevant double<->string conversion routines and these.
Get the individual parts (mantisse,exponent,sign) from the double, round them properly and put them in the 32-bits value. Watch out for special encoding schemes (like not storing the first bit of the mantissa, or having a biassed exponent, which means that an exponent x (e.g. an exponent -127<x<127 is stored as x+128)
Re: Math Guru III How to normalize floating point ?
hello Joshy
hope you will not be offended by a beginner's response, here's a small test for double
hope you will not be offended by a beginner's response, here's a small test for double
Code: Select all
union dbl
as double df
as ulongint li
end union
dim as dbl pi
pi.df=3.141592653589793*10 '31.41592653589793
dim as ulongint m, x=pi.li
dim as long expbits=11, expbias=1023, mbits=52, sign, e
e=x shr mbits 'get the 12 most significant bits
sign=(e and &h800) shr expbits 'zero-out all but the sign bit
e=e and &h7ff 'zero-out the sign bit
m=x and &b000000000001111111111111111111111111111111111111111111111111111 '52 + one implied mantissa bits
m=m or &b000000000010000000000000000000000000000000000000000000000000000 'set bit 53 in the mantissa
print hex(x),hex(m),m,hex(e),e,sign
print "sign=";sign," abs double value = ",m/(2^(expbias-e+mbits))
if (e-expbias)>0 and (e-expbias)<52 then
print "sign=";sign," abs integer part = ",m shr (expbias-e+mbits) 'integer part
end if
Last edited by srvaldez on Oct 27, 2016 0:26, edited 2 times in total.
Re: Math Guru III How to normalize floating point ?
While DuckDuckGoing, I found this: http://www.atarimagazines.com/compute/i ... OUTINE.php
Is this what you are looking for?
Is this what you are looking for?
-
- Posts: 8586
- Joined: May 28, 2005 3:28
- Contact:
Re: Math Guru III How to normalize floating point ?
thanks guys here are my first naive try.
i know left most bit (if set) of the matissa = 0.5 the second = 0.25 the third = 0.625 and so on ...
if the sign bit are set then the exponent are negative ...
NOTE: The IEEE-754 standard are defined in 1985 my (retro) Am9511 are one decade older (~1976) so it use it's own floating point format !
IEEE-754 = FPU (floating point unit)
Am9511 = APU (arithmetic processing unit)
Joshy
i know left most bit (if set) of the matissa = 0.5 the second = 0.25 the third = 0.625 and so on ...
if the sign bit are set then the exponent are negative ...
NOTE: The IEEE-754 standard are defined in 1985 my (retro) Am9511 are one decade older (~1976) so it use it's own floating point format !
IEEE-754 = FPU (floating point unit)
Am9511 = APU (arithmetic processing unit)
Joshy
Code: Select all
' Am9511
const as ulong sign_mask = &B10000000000000000000000000000000
const as ulong expo_mask = &B01111111000000000000000000000000
const as ulong mant_mask = &B00000000111111111111111111111111
' PI in Am9511 binary format
const as ulong Am9511_PI = &H02C90FDA
' PI in IEEE 754 format
dim as single PI = atn(1)*4
function floatToString(byval value as ulong) as string
dim as single exponent = 2 ^ ((value and expo_mask) shr 24)
dim as single mantisse = value and mant_mask
dim as single bitval = .5
dim as integer bitpos = 2^23
dim as single result
if (value and sign_mask) then exponent=-exponent
for i as integer = 1 to 23
if (mantisse and bitpos) then result += bitval
bitval *=0.5
bitpos shr=1
next
return str(exponent * result)
end function
print "single " & str(pi)
print "Am9511 " & floatToString(Am9511_PI)
print "Am9511" & floatToString(Am9511_PI or sign_mask)
print
print "IEEE 754 0x" & hex(*cast(long ptr,@pi),8)
print "Am9511 0x" & hex(Am9511_PI,8)
print
print "IEEE 754 " & bin(*cast(long ptr,@pi),32)
print "Am9511 " & bin(Am9511_PI,32)
sleep
Re: Math Guru III How to normalize floating point ?
made a correction in my example code, I thought that I could set the 53rd bit with and but it does not always work, so I changed the mantissa mask to 52-bits and set the 53rd bit with or, also changed some variable types to prevent incorrect result when using unsigned integer.
-
- Posts: 8586
- Joined: May 28, 2005 3:28
- Contact:
Re: Math Guru III How to normalize floating point ?
Looks like my naive way works for PI in both directions.
But i'm waiting for a math genius to get a more clever solution.
Joshy
But i'm waiting for a math genius to get a more clever solution.
Joshy
Code: Select all
' Am9511
const as ulong sign_mask = &B10000000000000000000000000000000
const as ulong expo_mask = &B01111111000000000000000000000000
const as ulong mant_mask = &B00000000111111111111111111111111
' PI in Am9511 binary format
const as ulong Am9511_PI = &H02C90FDA
' PI in IEEE 754 format
dim as single PI = atn(1)*4
' build text from a 4 byte Am9511 binary floating point number
function LongToString(byval value as ulong) as string
dim as single exponent = 2 ^ ((value and expo_mask) shr 24)
dim as single mantisse = value and mant_mask
dim as single bitval = 1.0
dim as integer bitpos = 2^23
dim as single mantissa
if (value and sign_mask) then exponent=-exponent
for i as integer = 1 to 24
bitval *=0.5
if (mantisse and bitpos) then mantissa += bitval
bitpos shr=1
next
return str(mantissa * exponent)
end function
' build a 4 byte Am9511 binary floating point number from text
function StringToLong(byval txt as string) as ulong
dim as single bitval
dim as integer bitpos
dim as ulong result
var nChars = len(txt)
if nChars=0 then return result
dim as single value=val(txt)
if value=0 then return result
if value<0 then result =2^31 : value=-value
dim as single exponent=int(log(value)/log(2))+1
dim as single mantissa=value / 2 ^ exponent
if exponent>0 then
bitval=128.0 : bitpos=2^30
for i as integer=1 to 7
bitval /= 2
if exponent>=bitval then result or= bitpos : exponent -= bitval
bitpos shr= 1
next
else
result or=2^30 : bitval=-64.0 : bitpos=2^29
for i as integer = 2 to 7
bitval /= 2
if exponent>=bitval then result or= bitpos : exponent -= bitval
bitpos shr= 1
next
end if
bitval=1.0 : bitpos=2^23
for i as integer=8 to 31
bitval /= 2
if mantissa>=bitval then result or=bitpos : mantissa-=bitval
bitpos shr=1
next
return result
end function
print "single " & str(pi)
print "Am9511 " & LongToString(Am9511_PI)
print "Am9511" & LongToString(Am9511_PI or sign_mask)
var pi_binary = Stringtolong("3.1415926")
print "binary " & LongToString(pi_binary)
print
print "IEEE 754 " & bin(*cast(long ptr,@pi),32)
print "Am9511 " & bin(Am9511_PI,32)
print "PI " & bin(pi_binary,32)
print
print "IEEE 754 0x" & hex(*cast(long ptr,@pi),8)
print "Am9511 0x" & hex(Am9511_PI,8)
print "PI 0x" & hex(pi_binary,8)
sleep
-
- Posts: 8586
- Joined: May 28, 2005 3:28
- Contact:
Re: Math Guru III How to normalize floating point ?
Here are my last version looks like I run in to the "egg or chicken dilemma" !
Putting a float in the source code of my OS / assembler / linker / compiler means I must convert it to a 4 byte value (dec or hex)
loop: I use log() and ^ (power of) to convert the float to binary and the Am9511 has this commands
but I need first the binary value of the float's to use log and power on the Am9511 goto loop :-(
I hope a genius can help and give me a stringToLong function
that will only parse the ASCII chars and build the 4 byte binary value of it (without val(),log() and "^")
Without this more tricky function I have to write a cross compiler assembler at first.
Joshy
Putting a float in the source code of my OS / assembler / linker / compiler means I must convert it to a 4 byte value (dec or hex)
loop: I use log() and ^ (power of) to convert the float to binary and the Am9511 has this commands
but I need first the binary value of the float's to use log and power on the Am9511 goto loop :-(
I hope a genius can help and give me a stringToLong function
that will only parse the ASCII chars and build the 4 byte binary value of it (without val(),log() and "^")
Without this more tricky function I have to write a cross compiler assembler at first.
Joshy
Code: Select all
' Am9511
const as ulong sign_mask = &B10000000000000000000000000000000
const as ulong expo_mask = &B01111111000000000000000000000000
const as ulong mant_mask = &B00000000111111111111111111111111
' PI in IEEE 754 format
dim as single PI = atn(1)*4
' PI in Am9511 binary format
const as ulong Am9511_PI = &H02C90FDA
const as ulong Am9511_5 = &H03A00000
' build text from a 4 byte Am9511 binary floating point number
function LongToString(byval value as ulong) as string
dim as single exponent = 2 ^ ((value and expo_mask) shr 24)
dim as single mantisse = value and mant_mask
dim as single bitval = 1.0
dim as integer bitpos = 2^23
dim as single mantissa
if (value and sign_mask) then exponent=-exponent
for i as integer = 1 to 24
bitval *=0.5
if (mantisse and bitpos) then mantissa += bitval
bitpos shr=1
next
return str(mantissa * exponent)
end function
' build a 4 byte Am9511 binary floating point number from text
function StringToLong(byval txt as string) as ulong
dim as single bitval
dim as integer exponent,bitpos,bits
dim as ulong result
dim as single mantissa,value=val(txt)
if value=0 then return result
' set sign bit and make value positive abs()
if value<0 then result =2^31 : value=-value
' get integer exponent and mantissa
exponent=int(log(value)/log(2))+1
mantissa=value / 2 ^ exponent
if exponent>0 then ' positive 7 bit loop
bitval = 128 : bitpos = 2^30 : bits = 7
else ' negative 6 bit loop
bitval = -64 : bitpos = 2^29 : bits = 6 : result or=2^30
end if
' build bits of the exponent
for i as integer=1 to bits
bitval /= 2
if exponent>=bitval then result or= bitpos : exponent -= bitval
bitpos shr= 1
next
' build bits of the mantissa
bitval = 1 : bitpos = 2^23 : bits = 24
for i as integer=1 to bits
bitval /= 2
if mantissa>=bitval then result or= bitpos : mantissa -= bitval
bitpos shr=1
next
return result
end function
print "single " & str(pi)
print "Am9511 " & LongToString(Am9511_PI)
print "Am9511" & LongToString(Am9511_PI or sign_mask)
var pi_binary = Stringtolong("3.1415926")
print "binary " & LongToString(pi_binary)
print
print "IEEE 754 " & bin(*cast(long ptr,@pi),32)
print "Am9511 " & bin(Am9511_PI,32)
print "PI " & bin(pi_binary,32)
print
print "IEEE 754 0x" & hex(*cast(long ptr,@pi),8)
print "Am9511 0x" & hex(Am9511_PI,8)
print "PI 0x" & hex(pi_binary,8)
sleep
Last edited by D.J.Peters on Oct 27, 2016 13:01, edited 1 time in total.
-
- Posts: 8586
- Joined: May 28, 2005 3:28
- Contact:
Re: Math Guru III How to normalize floating point ?
Ok I write a cross assembler/linker/compiler suite :-)
Joshy
Joshy
-
- Posts: 8586
- Joined: May 28, 2005 3:28
- Contact:
Re: Math Guru III How to normalize floating point ?
Ups I overread your post and it's indeed very helpful.badidea wrote:While DuckDuckGoing, I found this: http://www.atarimagazines.com/compute/i ... OUTINE.php
Is this what you are looking for?
The good old 6502 assembler code is near the same as 6803 so I can read it without any problems.
More than two years ago but it`s never to late to say thank you.
Joshy