Why doesn't atof work?

Discussion in 'C++' started by Drew, Jan 20, 2004.

  1. Drew

    Drew Guest

    Hi:

    I'm having trouble getting atof() to accurately convert "3.1"
    Any ideas?



    Thank you,



    Drew





    #include <iostream>
    #include <math.h>

    using namespace std;

    int main(int argc, char* argv[])
    {

    float fNum;
    char cNumBuffer[]="3.1";
    fNum =(float)atof(cNumBuffer);
    //Why does this store 3.099999905 in fNum

    return 0;
    }
     
    Drew, Jan 20, 2004
    #1
    1. Advertising

  2. Drew

    Ron Natalie Guest

    "Drew" <> wrote in message news:JShPb.31911$...
    > //Why does this store 3.099999905 in fNum
    >

    Because that is the closest representable number (3.1 is almost surely not exactly
    representable in binary) after it's been converted back to decimal for printing.
     
    Ron Natalie, Jan 20, 2004
    #2
    1. Advertising

  3. Drew

    Jeff Schwab Guest

    Drew wrote:
    > Hi:
    >
    > I'm having trouble getting atof() to accurately convert "3.1"
    > Any ideas?
    >
    >
    >
    > Thank you,
    >
    >
    >
    > Drew
    >
    >
    >
    >
    >
    > #include <iostream>
    > #include <math.h>
    >
    > using namespace std;
    >
    > int main(int argc, char* argv[])
    > {
    >
    > float fNum;
    > char cNumBuffer[]="3.1";
    > fNum =(float)atof(cNumBuffer);
    > //Why does this store 3.099999905 in fNum
    >
    > return 0;
    > }
    >
    >



    What Ron said. Furthermore, 3.1 is provably unrepresentable as the
    traditional sum of a finite sequence of integer powers of two, since .1
    = 10^-1, and 10 has a prime factor other than two.

    The GCC maintainers list this as their most often reported non-bug.

    http://gcc.gnu.org/bugs.html#nonbugs

    You can get a specified number of significant or reliable digits using
    sprintf, or a more type-safe alternative. If you need to represent
    rational numbers with absolute accuracy, get a library that supports
    "common fractions." If you need to represent irrationals perfectly, you
    might start by searching for "continued fractions;" these will help with
    some of the non-transcendentals.

    Personally, I avoid floating-point numbers whenever possible. Von
    Neumann also thought any programmers worth their salt should be able to
    keep track of a radix point. If you must work with floating point
    numbers in the same way you work with integers (e.g., you want to
    compare them for equality), at least be careful to round them to a
    realistic number of significant digits first.
     
    Jeff Schwab, Jan 20, 2004
    #3
  4. Drew

    Drew Guest

    Thank you all for the great responces.
    This was the first time I had ever tried this group.
    Lots of smart people here!

    If I may, one last question?
    Suppose you wanted to write your floats to a text file and read them back
    exactly, how would you do it?

    Thank you.

    Drew




    "Jeff Schwab" <> wrote in message
    news:...
    > Drew wrote:
    > > Hi:
    > >
    > > I'm having trouble getting atof() to accurately convert "3.1"
    > > Any ideas?
    > >
    > >
    > >
    > > Thank you,
    > >
    > >
    > >
    > > Drew
    > >
    > >
    > >
    > >
    > >
    > > #include <iostream>
    > > #include <math.h>
    > >
    > > using namespace std;
    > >
    > > int main(int argc, char* argv[])
    > > {
    > >
    > > float fNum;
    > > char cNumBuffer[]="3.1";
    > > fNum =(float)atof(cNumBuffer);
    > > //Why does this store 3.099999905 in fNum
    > >
    > > return 0;
    > > }
    > >
    > >

    >
    >
    > What Ron said. Furthermore, 3.1 is provably unrepresentable as the
    > traditional sum of a finite sequence of integer powers of two, since .1
    > = 10^-1, and 10 has a prime factor other than two.
    >
    > The GCC maintainers list this as their most often reported non-bug.
    >
    > http://gcc.gnu.org/bugs.html#nonbugs
    >
    > You can get a specified number of significant or reliable digits using
    > sprintf, or a more type-safe alternative. If you need to represent
    > rational numbers with absolute accuracy, get a library that supports
    > "common fractions." If you need to represent irrationals perfectly, you
    > might start by searching for "continued fractions;" these will help with
    > some of the non-transcendentals.
    >
    > Personally, I avoid floating-point numbers whenever possible. Von
    > Neumann also thought any programmers worth their salt should be able to
    > keep track of a radix point. If you must work with floating point
    > numbers in the same way you work with integers (e.g., you want to
    > compare them for equality), at least be careful to round them to a
    > realistic number of significant digits first.
    >
     
    Drew, Jan 20, 2004
    #4
  5. Drew

    Drew Guest

    Thank you for the great responces.
    This was the first time I had ever been to this group.
    Lots of smart people here!

    One more question:
    How can you save some floats to a text file and read them back acurately?

    Thank you.
    Best regards,

    Drew



    "Jeff Schwab" <> wrote in message
    news:...
    > Drew wrote:
    > > Hi:
    > >
    > > I'm having trouble getting atof() to accurately convert "3.1"
    > > Any ideas?
    > >
    > >
    > >
    > > Thank you,
    > >
    > >
    > >
    > > Drew
    > >
    > >
    > >
    > >
    > >
    > > #include <iostream>
    > > #include <math.h>
    > >
    > > using namespace std;
    > >
    > > int main(int argc, char* argv[])
    > > {
    > >
    > > float fNum;
    > > char cNumBuffer[]="3.1";
    > > fNum =(float)atof(cNumBuffer);
    > > //Why does this store 3.099999905 in fNum
    > >
    > > return 0;
    > > }
    > >
    > >

    >
    >
    > What Ron said. Furthermore, 3.1 is provably unrepresentable as the
    > traditional sum of a finite sequence of integer powers of two, since .1
    > = 10^-1, and 10 has a prime factor other than two.
    >
    > The GCC maintainers list this as their most often reported non-bug.
    >
    > http://gcc.gnu.org/bugs.html#nonbugs
    >
    > You can get a specified number of significant or reliable digits using
    > sprintf, or a more type-safe alternative. If you need to represent
    > rational numbers with absolute accuracy, get a library that supports
    > "common fractions." If you need to represent irrationals perfectly, you
    > might start by searching for "continued fractions;" these will help with
    > some of the non-transcendentals.
    >
    > Personally, I avoid floating-point numbers whenever possible. Von
    > Neumann also thought any programmers worth their salt should be able to
    > keep track of a radix point. If you must work with floating point
    > numbers in the same way you work with integers (e.g., you want to
    > compare them for equality), at least be careful to round them to a
    > realistic number of significant digits first.
    >
     
    Drew, Jan 20, 2004
    #5
  6. Drew

    David Harmon Guest

    On Tue, 20 Jan 2004 16:28:57 -0600 in comp.lang.c++, "Drew"
    <> was alleged to have written:
    >I'm having trouble getting atof() to accurately convert "3.1"


    The usual answer to that is the same in C++ as it is in C, and is
    covered in Steve Summit's C FAQ. See the topic "14.1: When I set a
    float variable to, say, 3.1, why is printf printing it as 3.0999999?"
    It is always good to check the FAQ before posting. You can get the FAQ
    at:
    http://www.eskimo.com/~scs/C-faq/top.html
     
    David Harmon, Jan 21, 2004
    #6
  7. Drew

    MPBroida Guest

    Drew wrote:
    >
    > One more question:
    > How can you save some floats to a text file and read them back acurately?


    Well, this method is probably not recommended, but it
    will get you the EXACT same value, provided you read
    in on the same architecture it was printed from.

    Print the float using a HEX format with enough digits
    to cover the entire variable. Then read it back in
    using the same HEX format. What you're doing in this
    case is effectively printing the exact BIT representation
    of the number using HEX notation. When you read it in
    the same way, you reproduce the same bit pattern. THEN
    looking at it as a float it will be the same as before.

    NOTE: I have not tried this in C/C++, but have done it
    in other languages. I'm not sure exactly what you might
    have to do (casts/etc) to make the Read step work right.
    Play with it awhile and see what you get. If you get
    it working, post it here so others can see it. :)

    Mike
     
    MPBroida, Jan 21, 2004
    #7
  8. Drew

    Bret Pehrson Guest

    Depends on the level of precision required. Presuming 1 decimal place:

    write:

    fprintf(file, "%.1f\n", float_value);

    read:

    fscanf(file, "%f\n", &float_value);


    Drew wrote:
    >
    > Thank you for the great responces.
    > This was the first time I had ever been to this group.
    > Lots of smart people here!
    >
    > One more question:
    > How can you save some floats to a text file and read them back acurately?
    >
    > Thank you.
    > Best regards,
    >
    > Drew
    >
    > "Jeff Schwab" <> wrote in message
    > news:...
    > > Drew wrote:
    > > > Hi:
    > > >
    > > > I'm having trouble getting atof() to accurately convert "3.1"
    > > > Any ideas?
    > > >
    > > >
    > > >
    > > > Thank you,
    > > >
    > > >
    > > >
    > > > Drew
    > > >
    > > >
    > > >
    > > >
    > > >
    > > > #include <iostream>
    > > > #include <math.h>
    > > >
    > > > using namespace std;
    > > >
    > > > int main(int argc, char* argv[])
    > > > {
    > > >
    > > > float fNum;
    > > > char cNumBuffer[]="3.1";
    > > > fNum =(float)atof(cNumBuffer);
    > > > //Why does this store 3.099999905 in fNum
    > > >
    > > > return 0;
    > > > }
    > > >
    > > >

    > >
    > >
    > > What Ron said. Furthermore, 3.1 is provably unrepresentable as the
    > > traditional sum of a finite sequence of integer powers of two, since .1
    > > = 10^-1, and 10 has a prime factor other than two.
    > >
    > > The GCC maintainers list this as their most often reported non-bug.
    > >
    > > http://gcc.gnu.org/bugs.html#nonbugs
    > >
    > > You can get a specified number of significant or reliable digits using
    > > sprintf, or a more type-safe alternative. If you need to represent
    > > rational numbers with absolute accuracy, get a library that supports
    > > "common fractions." If you need to represent irrationals perfectly, you
    > > might start by searching for "continued fractions;" these will help with
    > > some of the non-transcendentals.
    > >
    > > Personally, I avoid floating-point numbers whenever possible. Von
    > > Neumann also thought any programmers worth their salt should be able to
    > > keep track of a radix point. If you must work with floating point
    > > numbers in the same way you work with integers (e.g., you want to
    > > compare them for equality), at least be careful to round them to a
    > > realistic number of significant digits first.
    > >


    --
    Bret Pehrson
    mailto:
    NOSPAM - Include this key in all e-mail correspondence <<38952rglkwdsl>>
     
    Bret Pehrson, Jan 22, 2004
    #8
  9. Drew

    Jeff Schwab Guest

    Drew wrote:
    > Thank you all for the great responces.
    > This was the first time I had ever tried this group.
    > Lots of smart people here!
    >
    > If I may, one last question?
    > Suppose you wanted to write your floats to a text file and read them back
    > exactly, how would you do it?
    >
    > Thank you.
    >
    > Drew
    >
    >
    >
    >
    > "Jeff Schwab" <> wrote in message
    > news:...
    >
    >>Drew wrote:
    >>
    >>>Hi:
    >>>
    >>>I'm having trouble getting atof() to accurately convert "3.1"
    >>>Any ideas?
    >>>
    >>>
    >>>
    >>>Thank you,
    >>>
    >>>
    >>>
    >>>Drew
    >>>
    >>>
    >>>
    >>>
    >>>
    >>>#include <iostream>
    >>>#include <math.h>
    >>>
    >>>using namespace std;
    >>>
    >>>int main(int argc, char* argv[])
    >>>{
    >>>
    >>> float fNum;
    >>> char cNumBuffer[]="3.1";
    >>> fNum =(float)atof(cNumBuffer);
    >>> //Why does this store 3.099999905 in fNum
    >>>
    >>> return 0;
    >>>}
    >>>
    >>>

    >>
    >>
    >>What Ron said. Furthermore, 3.1 is provably unrepresentable as the
    >>traditional sum of a finite sequence of integer powers of two, since .1
    >>= 10^-1, and 10 has a prime factor other than two.
    >>
    >>The GCC maintainers list this as their most often reported non-bug.
    >>
    >> http://gcc.gnu.org/bugs.html#nonbugs
    >>
    >>You can get a specified number of significant or reliable digits using
    >>sprintf, or a more type-safe alternative. If you need to represent
    >>rational numbers with absolute accuracy, get a library that supports
    >>"common fractions." If you need to represent irrationals perfectly, you
    >>might start by searching for "continued fractions;" these will help with
    >>some of the non-transcendentals.
    >>
    >>Personally, I avoid floating-point numbers whenever possible. Von
    >>Neumann also thought any programmers worth their salt should be able to
    >>keep track of a radix point. If you must work with floating point
    >>numbers in the same way you work with integers (e.g., you want to
    >>compare them for equality), at least be careful to round them to a
    >>realistic number of significant digits first.
    >>

    >
    >
    >

    #include <fstream>
    #include <iomanip>
    #include <iostream>
    #include <string>

    struct Exception
    {
    Exception( char const* p ): m_what( p ) { }
    std::string const& what( ) const { return m_what; }
    private:
    std::string const m_what;
    };

    void write( double d )
    {
    std::eek:fstream out( "file" );

    if( ! out )
    {
    throw Exception( "can't write file" );
    }

    out << std::fixed << std::setprecision( 1000 ) << d;
    }

    double read( )
    {
    std::ifstream in( "file" );

    if( ! in )
    {
    throw Exception( "can't read file" );
    }

    double d;

    in >> d;

    return d;
    }

    int main( )
    try
    {
    float f( .1 );

    write( f + 3 );

    std::cout << std::fixed << std::setprecision( 1000 ) << read( )
    << "\n";
    }
    catch( Exception const& x )
    {
    std::cerr << x.what( ) << '\n';
    return 1;
    }
     
    Jeff Schwab, Jan 22, 2004
    #9
  10. Drew

    Bret Pehrson Guest

    > Von
    > Neumann also thought any programmers worth their salt should be able to
    > keep track of a radix point.


    Bret thought that any programmer worth their salt would use the *appropriate*
    numeric type and not create more work by needlessly keeping track of a radix.

    Jeff Schwab wrote:
    >
    > Drew wrote:
    > > Hi:
    > >
    > > I'm having trouble getting atof() to accurately convert "3.1"
    > > Any ideas?
    > >
    > >
    > >
    > > Thank you,
    > >
    > >
    > >
    > > Drew
    > >
    > >
    > >
    > >
    > >
    > > #include <iostream>
    > > #include <math.h>
    > >
    > > using namespace std;
    > >
    > > int main(int argc, char* argv[])
    > > {
    > >
    > > float fNum;
    > > char cNumBuffer[]="3.1";
    > > fNum =(float)atof(cNumBuffer);
    > > //Why does this store 3.099999905 in fNum
    > >
    > > return 0;
    > > }
    > >
    > >

    >
    > What Ron said. Furthermore, 3.1 is provably unrepresentable as the
    > traditional sum of a finite sequence of integer powers of two, since .1
    > = 10^-1, and 10 has a prime factor other than two.
    >
    > The GCC maintainers list this as their most often reported non-bug.
    >
    > http://gcc.gnu.org/bugs.html#nonbugs
    >
    > You can get a specified number of significant or reliable digits using
    > sprintf, or a more type-safe alternative. If you need to represent
    > rational numbers with absolute accuracy, get a library that supports
    > "common fractions." If you need to represent irrationals perfectly, you
    > might start by searching for "continued fractions;" these will help with
    > some of the non-transcendentals.
    >
    > Personally, I avoid floating-point numbers whenever possible. Von
    > Neumann also thought any programmers worth their salt should be able to
    > keep track of a radix point. If you must work with floating point
    > numbers in the same way you work with integers (e.g., you want to
    > compare them for equality), at least be careful to round them to a
    > realistic number of significant digits first.


    --
    Bret Pehrson
    mailto:
    NOSPAM - Include this key in all e-mail correspondence <<38952rglkwdsl>>
     
    Bret Pehrson, Jan 22, 2004
    #10
  11. Drew

    Jeff Schwab Guest

    Bret Pehrson wrote:
    >>Von
    >>Neumann also thought any programmers worth their salt should be able to
    >>keep track of a radix point.

    >
    >
    > Bret thought that any programmer worth their salt would use the *appropriate*
    > numeric type and not create more work by needlessly keeping track of a radix.


    And I would agree, provided one understands the limitations of the types
    being considered and not just their benefits.
     
    Jeff Schwab, Jan 23, 2004
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Pete C.

    atof() and _tstof() in VC6.0

    Pete C., Jun 24, 2004, in forum: C++
    Replies:
    9
    Views:
    7,316
    Ian Semmel
    Jun 24, 2004
  2. Replies:
    2
    Views:
    3,168
  3. Sharon
    Replies:
    4
    Views:
    1,073
    CBFalconer
    Nov 17, 2003
  4. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,226
    Smokey Grindel
    Dec 2, 2006
  5. perien

    why won't atof work here?

    perien, Jun 12, 2010, in forum: C Programming
    Replies:
    0
    Views:
    491
    perien
    Jun 12, 2010
Loading...

Share This Page