stringstream and double's

B

bob

Hi,

this is driving me insane. I have 2 strings which I want to convert to
doubles. To this effect I have written a function;

// we'll ignore error handing for the moment
void stringToDouble( const std::string& chars, double& retVal )
{
std::stringstream str;
str << chars;
str >> retVal;
}

this code;


double d = 0;


std::string aDouble("12.12305000012");
::stringToFloat(aDouble,d);
cout << "d: " << d << endl;

double d2 = 0;
std::string aDouble2("1234.643434439");
::stringToFloat(aDouble2,d2);
cout << "d2: " << d2 << endl;


Produces this output;

d: 12.123050000119999
d2: 1234.643434439





d is obviously not what i put into the string. could anybody grace me
with details of;

1) what the issue is?
2) what can I do to have my "d" variable match precisely what i put
into the string. I've just cout'ed the results here but in real life
the value will be used in a mathematical function so i cant have
rounding/precision loss.

thanks much for any help

G
 
B

Bo Persson

Hi,

this is driving me insane. I have 2 strings which I want to convert
to doubles. To this effect I have written a function;

// we'll ignore error handing for the moment
void stringToDouble( const std::string& chars, double& retVal )
{
std::stringstream str;
str << chars;
str >> retVal;
}

this code;


double d = 0;


std::string aDouble("12.12305000012");
cout << "d: " << d << endl;

double d2 = 0;
std::string aDouble2("1234.643434439");
cout << "d2: " << d2 << endl;


Produces this output;

d: 12.123050000119999
d2: 1234.643434439





d is obviously not what i put into the string. could anybody grace
me with details of;

1) what the issue is?
2) what can I do to have my "d" variable match precisely what i put
into the string. I've just cout'ed the results here but in real life
the value will be used in a mathematical function so i cant have
rounding/precision loss.

The error seems to be around 0.000000000000001 or so.

That's probably as good as it gets. Deal with it!


Bo Persson
 
J

Jonathan Lee

d is obviously not what i put into the string. could anybody grace me
with details of;

1) what the issue is?

Rounding. The number you entered, 12.12305000012, is not exactly
representable with binary. The closest number would be
(223630800744998189007 / 2**64) which is approximately
12.12305000011999999998948615576.

In short, the machine cannot store the number you entered (in the
"usual" way).
2) what can I do to have my "d" variable match precisely what i put
into the string.

You could implement some kind of BCD floating point if you're
expecting people to pass in decimal formatted strings. That's a very
special case, though, and won't save you in general.
i cant have rounding/precision loss.

Computers don't have infinite precision -- there will always be
numbers that will be rounded. Every time you do multiplication you'll
lose precision, for example. And almost every time you do addition,
etc. In computer science the best you can do is minimize this error.
Of course, in many applications the rounding error is smaller than
say, measurement error.

There are libs for arbitrary precision math if you look around.
They'll help some.
 
V

Victor Bazarov

this is driving me insane. I have 2 strings which I want to convert to
doubles. To this effect I have written a function;

// we'll ignore error handing for the moment
void stringToDouble( const std::string& chars, double& retVal )
{
std::stringstream str;
str << chars;

I think you could shorten it to

std::istringstream str(chars);
str >> retVal;
}

this code;


double d = 0;


std::string aDouble("12.12305000012");
::stringToFloat(aDouble,d);
cout << "d: " << d << endl;

double d2 = 0;
std::string aDouble2("1234.643434439");
::stringToFloat(aDouble2,d2);
cout << "d2: " << d2 << endl;


Produces this output;

d: 12.123050000119999

If you shorten the output to the same number of characters you entered
as the input, you'd get your original string.
d2: 1234.643434439





d is obviously not what i put into the string. could anybody grace me
with details of;

1) what the issue is?

Issue? The representation of doubles in the computer is not precise.
See if you get something useful from this document:

http://docs.sun.com/source/806-3568/ncg_goldberg.html

2) what can I do to have my "d" variable match precisely what i put
into the string.

Nothing, in most cases.
> I've just cout'ed the results here but in real life
the value will be used in a mathematical function so i cant have
rounding/precision loss.

If you can't have rounding/precition loss, you shouldn't use the regular
"double" for your floating point calculations. Use rationals, use
arbitrary precision math kernel...

V
 
J

James Kanze

this is driving me insane. I have 2 strings which I want to
convert to doubles. To this effect I have written a function;
// we'll ignore error handing for the moment
void stringToDouble( const std::string& chars, double& retVal )
{
std::stringstream str;
str << chars;
str >> retVal;
}

Why not just:

double
toDouble( std::string const& in )
{
std::istringstream s( in ) ;
double result ;
s >> result ;
return result ;
}

(Of course, you really need some error handling code as well.)
this code;
double d = 0;
std::string aDouble("12.12305000012");
::stringToFloat(aDouble,d);
cout << "d: " << d << endl;
double d2 = 0;
std::string aDouble2("1234.643434439");
::stringToFloat(aDouble2,d2);
cout << "d2: " << d2 << endl;
Produces this output;
d: 12.123050000119999
d2: 1234.643434439

Something's wrong (or you haven't showed us everything). By
default, precision is 6, so you should get:
d: 12.1231
d2: 1234.64
(And that's what g++ gives.)
d is obviously not what i put into the string.

Since d isn't a string, it hardly could be, could it. You put
characters into a string, and d doesn't have any characters.

It's highly likely that the value of d doesn't correspond
exactly to the value of the string you passed it. In either
case: in most of the usual floating point representations, the
values you give aren't representable, so the variable obviously
can't contain them. The value of d is probably very close to
the value you gave, however---on a PC or most Unix platforms
(which all use IEEE arithmetic), the difference probably doesn't
show up until about the 16th decimal.

If you're doing anything using floating point, you probably
should have read "What Every Computer Scientist Should Know
About Floating-Point Arithmetic"
(http://docs.sun.com/source/806-3568/ncg_goldberg.html).

And finally, of course, "cout << d" does not display "what's in
d". It converts what's in d to a string, with a given precision
(6 decimal digits by default).
could anybody grace me with details of;
1) what the issue is?

See the reference, above.
2) what can I do to have my "d" variable match precisely what i put
into the string.

You can't, in general. Anymore than you can precisely express
one third as a finite decimal.
I've just cout'ed the results here but in real life the value
will be used in a mathematical function so i cant have
rounding/precision loss.

You will have rounding and loss of precision. Machine floating
point is a discrete representation of a finite subset of all
possible real numbers. Read the article cited above, and until
you've understood it, hands off floating point.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top