Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Why doesn't atof work?

Reply
Thread Tools

Why doesn't atof work?

 
 
Drew
Guest
Posts: n/a
 
      01-20-2004
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;
}


 
Reply With Quote
 
 
 
 
Ron Natalie
Guest
Posts: n/a
 
      01-20-2004

"Drew" <(E-Mail Removed)> wrote in message news:JShPb.31911$(E-Mail Removed). ..
> //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.


 
Reply With Quote
 
 
 
 
Jeff Schwab
Guest
Posts: n/a
 
      01-20-2004
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.

 
Reply With Quote
 
Drew
Guest
Posts: n/a
 
      01-20-2004
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" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> 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.
>



 
Reply With Quote
 
Drew
Guest
Posts: n/a
 
      01-20-2004
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" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> 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.
>



 
Reply With Quote
 
David Harmon
Guest
Posts: n/a
 
      01-21-2004
On Tue, 20 Jan 2004 16:28:57 -0600 in comp.lang.c++, "Drew"
<(E-Mail Removed)> 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


 
Reply With Quote
 
MPBroida
Guest
Posts: n/a
 
      01-21-2004
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
 
Reply With Quote
 
Bret Pehrson
Guest
Posts: n/a
 
      01-22-2004
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" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
> > 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
(E-Mail Removed)
NOSPAM - Include this key in all e-mail correspondence <<38952rglkwdsl>>
 
Reply With Quote
 
Jeff Schwab
Guest
Posts: n/a
 
      01-22-2004
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" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>
>>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: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;
}

 
Reply With Quote
 
Bret Pehrson
Guest
Posts: n/a
 
      01-22-2004
> 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
(E-Mail Removed)
NOSPAM - Include this key in all e-mail correspondence <<38952rglkwdsl>>
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
why won't atof work here? perien C++ 0 06-11-2010 11:16 PM
findcontrol("PlaceHolderPrice") why why why why why why why why why why why Mr. SweatyFinger ASP .Net 2 12-02-2006 03:46 PM
locale independent atof? sprotty@hotmail.com C++ 2 01-17-2005 03:37 PM
atof() and _tstof() in VC6.0 Pete C. C++ 9 06-24-2004 09:38 PM
what are the reverse functions of atof( ), atoi( ) and atol( ) ? Sharon C Programming 4 11-17-2003 10:13 AM



Advertisments