Shop OBEX P1 Docs P2 Docs Learn Events
My ASCII2Float function — Parallax Forums

My ASCII2Float function

James NewmanJames Newman Posts: 133
edited 2007-12-10 22:41 in Propeller 1
After squashing my last bug, I got back to work on my current project, and the next thing was to parse my input string and return a floating point number. There was a thread somewhere that had a method for doing this, I don't have the time to dig it up atm. I modified the code to suit my needs, and went a little extra since I thought it might be useful for others. The first snippet of code is more forgiving. IE: if you feed it ' 43-2. 9.+5' it would come back with '-432.95'. The second snippet has a second parameter 'strict'. If false, it should behave like the first snippet, only slower. If 'strict' is true, however, it will return the value $7FFF_FFFF on invalid syntax, which is defined as 'NaN' in Float32. (Maybe in the IEEE specs?) A valid syntax would be an optional '+' or '-' as the first character of the string, and one optional '.' somewhere in the string. All other characters must be numeric. Spaces are not allowed either, which may mean you need to trim leading and trailing spaces before use. If anyone feels it's worth it, I'll look up the appropriate credits, and add this to the object exchange.

Both snippets require a floating point object named 'fp'. I believe any of the popular ones should work.

Tolerant code, faster than the 'strict' capable snippet.
PUB string2Float(address) | c, d, dp, n
  'Convert an ASCII string to a float (VERY TOLERANT)
  d := false
  dp := 1
  n := false

  repeat
    case c := byte[noparse][[/noparse] address++ ]
      "0".."9": result := result * 10 + (c - "0")
                if d
                  dp := dp * 10
      ".": d := true                                    'Could add check for already being true
      "-": n := true                                    ' and if so, error, on .,-, and + signs.
      "+": next
      0: quit                                           'Null byte, done parsing
      other: next                                       'Could error here
  result := fp.fdiv(fp.ffloat(result),fp.ffloat(dp))
  if n
    result := fp.fneg(result)




'Strict' parameter code.
PUB string2Float(address,strict) | c, d, dp, n
  'Convert an ASCII string to a float
  d := false
  dp := 1
  n := false

  if (c := byte[noparse][[/noparse] address ]) == "-"
    n := true
    address++
  elseif c == "+"
    address++
  
  repeat
    case c := byte[noparse][[/noparse] address++ ]
      "0".."9": result := result * 10 + (c - "0")
                if d
                  dp := dp * 10
      ".": if strict
             ifnot d
               d := true
             else
               return $7FFF_FFFF                        'NaN for error
           else
             d := true
      0: quit                                           'Null byte, done parsing
      other: if strict
               return $7FFF_FFFF
  result := fp.fdiv(fp.ffloat(result),fp.ffloat(dp))
  if n
    result := fp.fneg(result)




EDIT: Removed some trailing spaces that where stretching the post horizontally.

Post Edited (James Newman) : 12/10/2007 2:21:51 AM GMT

Comments

  • deSilvadeSilva Posts: 2,967
    edited 2007-12-10 14:00
    Why not also handle "scientific" input? 1.5e3
    I see a minor optimization:
    CASE "-": result := - result
    


    .. and then omitt he last two lines completely
  • James NewmanJames Newman Posts: 133
    edited 2007-12-10 19:36
    Well scientific notation complicates it a bit more. I might add it, but my application doesn't require it, so it'd be later if I do.

    Your optimization wouldn't work to well with the line '"0".."9": result := result * 10 + (c - "0")'. However, I could move the last two lines before the conversion to float, and make the integer value negative there. That would be faster.
  • deSilvadeSilva Posts: 2,967
    edited 2007-12-10 22:41
    James Newman said...
    Your optimization wouldn't work too well with the line '"0".."9": result := result * 10 + (c - "0")'.

    smile.gif Right you are!!
Sign In or Register to comment.