Shop OBEX P1 Docs P2 Docs Learn Events
C: Problems with atof and strtod fuctions within SimpleIDE — Parallax Forums

C: Problems with atof and strtod fuctions within SimpleIDE

idbruceidbruce Posts: 6,197
edited 2015-04-01 02:09 in Propeller 1
I was always more an atoi kind of guy, but with this GCODE stuff and the floating points, I am now having to use the other available functions. Of course there could be a situation that I am unaware of, but this just seems very odd to me. In reference to the terminal output below, the upper line is the string representation and the lower line is the numeric representation. X, Y, Z, E, & F are all doubles and have been tested with both the atof and strtod functions, and both produce similar results.
Fileline: G1 X11.11 Y22.22 Z0.12 E0 F30000
Valid GCODE Fields: 10000111111
G: 1, X: 11.11, Y: 22.22, Z: 0.12, E: 0, F: 30000, 
G: 1, X: 11.110000, Y: 22.219999, Z: 0.120000, E: 0.000000, F: 30000.000000, 

Fileline: G1 X33.33 Y44.44 Z0.1 E0 F222
Valid GCODE Fields: 10000111111
G: 1, X: 33.33, Y: 44.44, Z: 0.1, E: 0, F: 222, 
G: 1, X: 33.330002, Y: 44.439999, Z: 0.100000, E: 0.000000, F: 222.000000, 

Fileline: G1 E1.23 F900
Valid GCODE Fields: 10000000111
G: 1, E: 1.23, F: 900, 
G: 1, E: 1.230000, F: 900.000000, 

Fileline: G1 X55.55 Y66.66 E0.0102 F555
Valid GCODE Fields: 10000110111
G: 1, X: 55.55, Y: 66.66, E: 0.0102, F: 555, 
G: 1, X: 55.549999, Y: 66.660004, E: 0.010200, F: 555.000000, 

Fileline: G1 X77.77 Y88 E0.1234
Valid GCODE Fields: 10000110101
G: 1, X: 77.77, Y: 88, E: 0.1234, 
G: 1, X: 77.769997, Y: 88.000000, E: 0.123400, 

Fileline: G1 X-11.11 Y-22.22 Z0.12 E0 F30000
Valid GCODE Fields: 10000111111
G: 1, X: -11.11, Y: -22.22, Z: 0.12, E: 0, F: 30000, 
G: 1, X: -11.110000, Y: -22.219999, Z: 0.120000, E: 0.000000, F: 30000.000000, 

Fileline: G1 X-33.33 Y-44.44 Z0.1 E0 F222
Valid GCODE Fields: 10000111111
G: 1, X: -33.33, Y: -44.44, Z: 0.1, E: 0, F: 222, 
G: 1, X: -33.330002, Y: -44.439999, Z: 0.100000, E: 0.000000, F: 222.000000, 

Fileline: G1 E-1.23 F900
Valid GCODE Fields: 10000000111
G: 1, E: -1.23, F: 900, 
G: 1, E: -1.230000, F: 900.000000, 

Fileline: G1 X-55.55 Y-66.66 E-0.0102 F555
Valid GCODE Fields: 10000110111
G: 1, X: -55.55, Y: -66.66, E: -0.0102, F: 555, 
G: 1, X: -55.549999, Y: -66.660004, E: -0.010200, F: 555.000000, 

Fileline: G1 X-77.77 Y-88 E-0.1234
Valid GCODE Fields: 10000110101
G: 1, X: -77.77, Y: -88, E: -0.1234, 
G: 1, X: -77.769997, Y: -88.000000, E: -0.123400, 

Fileline: G1 F1200 X0 Y0 Z23
Valid GCODE Fields: 10000111011
G: 1, X: 0, Y: 0, Z: 23, F: 1200, 
G: 1, X: 0.000000, Y: 0.000000, Z: 23.000000, F: 1200.000000, 

11 total lines

Comments

  • Dave HeinDave Hein Posts: 6,347
    edited 2015-03-31 16:20
    So what's the question?
  • idbruceidbruce Posts: 6,197
    edited 2015-03-31 16:27
    LOL Why doesn't the atof output match the string version output? The string versions are character arrays. Do I need to buffer[end_position] = '\0'; to get a correct response from atof?
  • idbruceidbruce Posts: 6,197
    edited 2015-03-31 16:29
    For example

    55.55 string output
    55.549999 numeric output after atof
  • Dave HeinDave Hein Posts: 6,347
    edited 2015-03-31 16:32
    But they do match, except for some of the lesser significant digits. If you printed the numbers in the same format of the string they would match exactly. You would need to use formats like "%5.2f" and other similar formats to match the string. You do know that 32-bit floating point is only accurate to about 6 decimal digits, right?
  • idbruceidbruce Posts: 6,197
    edited 2015-03-31 16:40
    You do know that 32-bit floating point is only accurate to about 6 decimal digits, right?

    Nope, I didn't know that.
    You would need to use formats like "%5.2f" and other similar formats to match the string.

    Hmmm.... I was hoping the floating points would match for mathematical reasons instead of actual print, but I supoose rounding would do the trick.
  • DavidZemonDavidZemon Posts: 2,973
    edited 2015-03-31 18:07
    This is one of the few unfortunate side effects of our computers being based on base 2 instead of base 10 (like we have a choice...). Some numbers need a lot more digits to be accurately represented. This issue of rounding causes all kinds of headaches in all sorts of different industries. When speed isn't an issue, you using something like "BigDecimal" which doesn't use IEEE floating point representation. You loose speed but gain absolute precision (at least, absolute relative to anything that can be expressed in base 10).
  • ersmithersmith Posts: 6,053
    edited 2015-03-31 18:09
    As Dave said, 32 bit floats are only accurate to about 7 decimal digits (and 64 bit doubles to about 16 digits). The other wrinkle in floating point is that 1/10 (0.1 in decimal) is not exactly representable in binary: just as 1/3 is the infinite decimal sequence 0.33333..., 1/10 gives the infinite binary sequence 0.00011001100110011... Combined with the limited precision of floating point numbers, this fact makes working with floating point tricky. Results can be pretty surprising sometimes.

    That said, the strtod and printf functions that come with SimpleIDE are not very careful about precision, and do a poor job with very large and very small numbers. The ones in the default branch of PropGCC are quite a bit better, and the ones in the new proplib C library are better still.

    Eric
  • idbruceidbruce Posts: 6,197
    edited 2015-03-31 23:26
    Thanks for the information everyone, because I was very surprised to see the results :)

    I certainly thought that it should be identical to the string respresentation :)

    I never really had the need to work with floating point numbers, except for perhaps percentages.

    Bitmaps, screen resolution, control size, etc... were always in whole numbers.

    Thanks again.
  • idbruceidbruce Posts: 6,197
    edited 2015-04-01 00:35
    Dave
    You would need to use formats like "%5.2f" and other similar formats to match the string.

    That works pretty darn good for the output. As for computations, I think I found some worthy snippets here: http://stackoverflow.com/questions/1343890/rounding-number-to-2-decimal-places-in-c
  • msrobotsmsrobots Posts: 3,709
    edited 2015-04-01 01:15
    @idbruce,

    I do not understand for what you need floats at all. Your G code has two digits behind the decimal point. Multiply by 100 and use 32 bit integers.

    float always introduces rounding errors. 0.1 + 0.2 is not equal 0.3.

    my 2 cents

    Mike
  • idbruceidbruce Posts: 6,197
    edited 2015-04-01 02:09
    Mike
    @idbruce,

    I do not understand for what you need floats at all. Your G code has two digits behind the decimal point. Multiply by 100 and use 32 bit integers.

    float always introduces rounding errors. 0.1 + 0.2 is not equal 0.3.

    my 2 cents

    Mike

    Believe me, I thought about going that route, BUT not all the floating points simply have two digits behind the decimal point, at which point, the parsing technique becomes much more lengthy, just to determine the exact location of the decimal point. However, I may end up going that route in the long run. My goal at this point is to keep the code very simple and short.
Sign In or Register to comment.