flat assembler
Message board for the users of flat assembler.

Index > Main > ASCII to Float (r80) algorithm

Author
Thread Post new topic Reply to topic
Chewy509



Joined: 19 Jun 2003
Posts: 297
Location: Bris-vegas, Australia
Chewy509
I've been reworking my atof() function, and have come up with the following. Any comments, or noticeable bugs would be appreciated.

Code:
atof alogrithm

; designed for x86/x64 systems

variables:

1. string pointer (string should be null terminated)
2. value sign
3. BCD String
4. bcd char count
5. number of decimal places
6. exponent sign
7. exponent value (less than 4930)

We break the string into distinct sections:

" +-  1234  . 567890 eE +- 1234 "
  ^     ^        ^    ^  ^   ^
  |     |        |    |  |   |
  sign  |        |    |  |   |
       abs value |    |  |   |
              decimal |  |   |
                Exp mark |   |
                   Exp Sign  |
                        Exp value

next char always stores in al / r0b

1.  Check for sign "+" or "-", set value sign flag accordingly/next char
2.  If "0", repeat until "1"-"9" or "."
3.  If "." goto 10
4.  Convert r0b to number - store in BCD string
5.  next char; inc BCD char count
6.  if "e" or "E" goto 16
7.  if BCD char count < 19 then goto 9
8.  while not "e", "E" or 'null' nextchar. if anything else error()
9.  goto 3
10. next char (load into r0b)
11. if "e" or "E" goto 14
12. if 'null' goto 25, or if anything other than "0"-"9" then error()
13. if BCD char count < 19 then convert r0b to number - store in BCD string
14. inc BCD char count; if BCD char count < 19 then inc decimal place count;  
15. goto 12
16. next char
17. Check for sign "+" or "-", set exp sign flag accordingly/next char
18. If "0", repeat until "1"-"9"
19. convert r0b to number, add to exp value
20. if 'null' goto 25
21. exp value * 10
22. If carry then error().
23. next char
24. goto 19
25. if exp value > 4930 then error()
26. pack BCD string, set BCD string load into FPU
27. flbd BCD string into ST0
28. fild 10 (STO = 10, ST1 = BCD String)
29. exp value = exp value - decimal count
30. if exp value > 4930 then error()
31. r1 = exp value; if r1 = 0 then goto 36
32. if exp value is + fmul st1, st0
33. if exp value is - fdiv st1, st0
34. dec r1
35. if r1 > 0 goto 32
36. pop top of FP stack = st0 is our value
37. if value sign is negative, fchs st0.
    


Based on the above, it should be pretty easy to convert to asm (or any other HLL)...

Does anyone have anything similar for ftoa()? where the end format is:
± 1 . 2345 e ± 6789

PS. my atof() and ftoa() currently don't handle the exponent, which is what I'm adding and would to ensure that I'm maintaining as much precision as possible...
Post 20 Feb 2007, 23:38
View user's profile Send private message Visit poster's website Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
FASM sources contain something like that in parser. ask tomasz for further pointing.
Post 21 Feb 2007, 00:29
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Chewy509



Joined: 19 Jun 2003
Posts: 297
Location: Bris-vegas, Australia
Chewy509
vid wrote:
FASM sources contain something like that in parser. ask tomasz for further pointing.

I've read through the fasm source, but really can't make head or tail of it?
Post 21 Feb 2007, 01:35
View user's profile Send private message Visit poster's website Reply with quote
farrier



Joined: 26 Aug 2004
Posts: 274
Location: North Central Mississippi
farrier
Chewy509,

You can look at Raymond Filiatreault's site where he has an FPU Tutorial, FPULib--with MASM source--, Complex number, Fixed Point Math, and Binary Coded Decimal sections. Designed for teaching/learning to use these tools!

http://www.ray.masmcode.com/

hth,

farrier

_________________
Some Assembly Required
It's a good day to code!
U.S.Constitution; Bill of Rights; Amendment 1:
... the right of the people peaceably to assemble, ...
The code is dark, and full of errors!
Post 21 Feb 2007, 08:50
View user's profile Send private message Reply with quote
shoorick



Joined: 25 Feb 2005
Posts: 1608
Location: Ukraine
shoorick
check a2f in shoolib - i wrote it long ago after study similar masm32 function. it exactly eats string into 80-bit float (thus possible slow) and has no restrictions on string length Smile i had not wrote f2a yet (as i had no neccessity in it yet), but there are a lot of ready examples.

_________________
UNICODE forever!
Post 21 Feb 2007, 09:06
View user's profile Send private message Visit poster's website Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
also note that FASM's a2f doesn't use FPU and so it has much better precision
Post 21 Feb 2007, 09:53
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Chewy509



Joined: 19 Jun 2003
Posts: 297
Location: Bris-vegas, Australia
Chewy509
Thanks guys. I'll check out those links.

Vid, after rereading the fasm source, I noticed that it doesn't use the FPU, a little strange, but if it works, it works. I guess that was stuffing me up when looking through the source, as I was expecting some FPU code?
Post 22 Feb 2007, 01:06
View user's profile Send private message Visit poster's website Reply with quote
ChrisLeslie



Joined: 04 Jun 2006
Posts: 50
Location: Australia
ChrisLeslie
Quote from shoorick:
Quote:
i had not wrote f2a yet (as i had no neccessity in it yet),


I am curious as to how you can visualise any final output floats that you may have produced without an f2a?

Chris
Post 22 Feb 2007, 04:22
View user's profile Send private message Reply with quote
shoorick



Joined: 25 Feb 2005
Posts: 1608
Location: Ukraine
shoorick
i saw it in debugger Very Happy
Post 22 Feb 2007, 05:39
View user's profile Send private message Visit poster's website Reply with quote
Chewy509



Joined: 19 Jun 2003
Posts: 297
Location: Bris-vegas, Australia
Chewy509
I've been thinking a lot about this recently and have looked at about 30 implementations of the atof(), however 1 implementation stood out in that it doesn't use lookup tables for the exponent and to be honest appears really simple.

It basically is along the lines of:

Code:
FILD word [exp] ; st0 = exponent
FLDL2T ; st0 = log2_10, st1 = exponent
FMULP st1; st0 = exp * log2_10
FBLD [sig] ; st0 = sig, st1 = exp
FSCALE ; st0 = st0 * 2 ^ st1
if value is neg then FCHS    


done! exp is the exponent biased accordingly for the imported significant taking into account the movement of the decimal when converting the significant to BCD.

eg: 100.123456e99, would be sig as bcd when loaded = 100123456 exp = 93 (as the decimal shits right we sub the places from exp, if decimal shifts left we add to the exp the number of places)

So how does it work? Well since we don't have a x^y instruction, we need to use:

x^y = 2^ (y * log2_x) or since we are using 10 ^ y
10^y = 2 ^ (y * log2_10) .

The great thing is, is that the x87 FPU contains log2_10 as a constant! eg FLDL2T!

And since our original form is: sig * 10 ^ exp we can use:

sig * (2 ^ (exp * log2_10))

based on the above knowledge.

Can anyone find anything wrong with this approach? Or did I miss something during my high school math classes?
Post 23 Feb 2007, 00:53
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.