Shop OBEX P1 Docs P2 Docs Learn Events
Parse floats from string speed contest — Parallax Forums

Parse floats from string speed contest

scottascotta Posts: 168
edited 2007-03-26 20:39 in Propeller 1
Can anyone see a faster way to parse floats than this ?


PUB ParseFloat(sptr) :retv | dptr,chr,sign
sign:=0
dptr:=0
retv:=0
repeat
if byte[noparse][[/noparse]sptr] <>" "
quit
sptr++
repeat
chr:=byte[noparse][[/noparse]sptr]
if chr==0
quit
elseif chr=="-"
sign:=-1.0
elseif chr=="."
dptr:=sptr
elseif chr =>48 AND chr =< 57
retv:=retv*10+(chr-48)
elseif chr==" "
quit
byte[noparse][[/noparse]sptr]:=" "
sptr++
retv:=f.fdiv(f.ffloat(retv),tenf[noparse][[/noparse]sptr-dptr-1])
if sign <> 0
retv:=f.fmul(retv,sign)

Comments

  • scottascotta Posts: 168
    edited 2007-03-25 00:03
    PUB ParseFloat(sptr) :retv | dptr,chr,sign
    sign:=0
    dptr:=0
    retv:=0
    repeat
    if byte[noparse][[/noparse]sptr] <>" "
    quit
    sptr++
    repeat
    chr:=byte[noparse][[/noparse]sptr]
    if chr==0
    quit
    elseif chr=="-"
    sign:=-1.0
    elseif chr=="."
    dptr:=sptr
    elseif chr =>48 AND chr =< 57
    retv:=retv*10+(chr-48)
    elseif chr==" "
    quit
    byte[noparse][[/noparse]sptr]:=" "
    sptr++
    retv:=f.fdiv(f.ffloat(retv),tenf[noparse][[/noparse]sptr-dptr-1])
    if sign <> 0
    retv:=f.fmul(retv,sign)
  • scottascotta Posts: 168
    edited 2007-03-25 00:04
    The post routine is removing the indentation....
  • Spork FrogSpork Frog Posts: 212
    edited 2007-03-25 00:08
    Use CODE tags instead. (For the indentation.)
  • scottascotta Posts: 168
    edited 2007-03-25 14:00
    [noparse][[/noparse]code]
    PUB ParseFloat(sptr) :retv | dptr,chr,sign
    sign:=0
    dptr:=0
    retv:=0
    repeat
    if byte[noparse][[/noparse]sptr] <>" "
    quit
    sptr++
    repeat
    chr:=byte[noparse][[/noparse]sptr]
    if chr==0
    quit
    elseif chr=="-"
    sign:=-1.0
    elseif chr=="."
    dptr:=sptr
    elseif chr =>48 AND chr =< 57
    retv:=retv*10+(chr-48)
    elseif chr==" "
    quit
    byte[noparse][[/noparse]sptr]:=" "
    sptr++
    retv:=f.fdiv(f.ffloat(retv),tenf[noparse][[/noparse]sptr-dptr-1])
    if sign <> 0
    retv:=f.fmul(retv,sign)
  • scottascotta Posts: 168
    edited 2007-03-25 14:01
    
    PUB ParseFloat(sptr)  :retv  | dptr,chr,sign
        sign:=0
        dptr:=0
        retv:=0
        repeat
            if byte[noparse][[/noparse]sptr] <>" "
                quit
            sptr++
        repeat
            chr:=byte[noparse][[/noparse]sptr]
            if chr==0
                quit
            elseif chr=="-"
                sign:=-1.0
            elseif chr=="."
                dptr:=sptr
            elseif chr =>48 AND chr =< 57   
                retv:=retv*10+(chr-48)
            elseif chr==" "
                quit
            byte[noparse][[/noparse]sptr]:=" "
            sptr++ 
        retv:=f.fdiv(f.ffloat(retv),tenf[noparse][[/noparse]sptr-dptr-1])
        if sign <> 0
            retv:=f.fmul(retv,sign)
    
    
    
  • rokickirokicki Posts: 1,000
    edited 2007-03-26 17:36
    It would be nice to have a definition of what the function is supposed to do, what valid input is,
    etc. For instance, your routine will not parse the string "5000000000" correctly. Also, what
    are the requirements on accuracy?

    Writing an acceptable string-to-float (and even float-to-string) is a very interesting, challenging,
    and fun task, but it is the details that will get you.
  • scottascotta Posts: 168
    edited 2007-03-26 18:08
    It has to be 100% accurate...

    I saw the error you pointed out this morning, here is the latest:

    PUB ParseFloat(sptr)  :retv  | dptr,chr,sign
        sign:=0
        dptr:=0
        retv:=0
        repeat
            if byte[noparse][[/noparse]sptr] <>" "
                quit
            sptr++
        repeat
            chr:=byte[noparse][[/noparse]sptr]
            if chr==0
                quit
            elseif chr=="-"
                sign:=-1.0
            elseif chr=="."
                dptr:=sptr
            elseif chr =>48 AND chr =< 57   
                retv:=retv*10+(chr-48)
            elseif chr==" "
                quit
            byte[noparse][[/noparse]sptr]:=" "
            sptr++
        
        retv:=f.ffloat(retv)
        if dptr <> 0
            retv:=f.fdiv(retv,tenf[noparse][[/noparse]sptr-dptr-1])
        if sign <> 0
            retv:=f.fmul(retv,sign)
    
    
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-26 18:17
    scotta,
    With floating point, unless you're talking about integer values with fewer significant digits than the maximum precision of the floating point, you will not get "100% accuracy". That's just inherent to floating point. You only get about 23-24 bits of accuracy which is about 7 decimal digits.
  • scottascotta Posts: 168
    edited 2007-03-26 18:38
    I should have re-worded that response. The parser needs to be 100% [noparse]:)[/noparse]
  • rokickirokicki Posts: 1,000
    edited 2007-03-26 20:39
    And the parser should be able to attain 100% accuracy (in the sense of returning the closest
    floating point value for a given input).

    But to make it reasonably easy perhaps an error of +/- 0.6ulp would be sufficiently
    precise (i.e., you don't require +/- 0.5ulp, but are willing to give up a small fraction of a
    ulp in order to simplify things).
Sign In or Register to comment.