471,337 Members | 1,053 Online

# Need help converting a string to a float...

I'm having this weird problem where my code does the following
conversion from string to float:

27000000.0 -27000000.00
2973999.99 -29740000.00
2989999.13 -2989999.25

The number on the left is the string I get after tokenizing a bigger
string. The number on the right is the number I get after the conversion.

I've tried two different ways of converting, one way the older C way
using atof, and another more C++ way. Either way, I get the same
result. Can anyone shed some light on this for me?

Here's the code:

string token;
string tokens;
stringstream iss;
getline(fin,bfr);
while (getline(fin, bfr))
{
iss << bfr;
i = 0;
while (getline(iss, token, ','))
{
tokens[i++] = token;
}

std::istringstream b(tokens);
b >price;

//price = atof(tokens.c_str());
Jun 7 '07 #1
10 3007 On Jun 7, 2:52 pm, Hank Stalica <u...@example.netwrote:
I'm having this weird problem where my code does the following
conversion from string to float:

27000000.0 -27000000.00
2973999.99 -29740000.00
2989999.13 -2989999.25

The number on the left is the string I get after tokenizing a bigger
string. The number on the right is the number I get after the conversion.

I've tried two different ways of converting, one way the older C way
using atof, and another more C++ way. Either way, I get the same
result. Can anyone shed some light on this for me?

Here's the code:

string token;
string tokens;
stringstream iss;
getline(fin,bfr);
while (getline(fin, bfr))
{
iss << bfr;
i = 0;
while (getline(iss, token, ','))
{
tokens[i++] = token;
}

std::istringstream b(tokens);
b >price;

//price = atof(tokens.c_str());
I don't think conversion is your problem, I think its your method of
outputting your numbers that is causing rounding and confusion...
JMO.
Jun 7 '07 #2
Could be.

Here's code I used to display the numbers side by side:

printf("%s %10.2f\n",tokens.c_str(), price);

On Jun 7, 2:52 pm, Hank Stalica <u...@example.netwrote:
>I'm having this weird problem where my code does the following
conversion from string to float:

27000000.0 -27000000.00
2973999.99 -29740000.00
2989999.13 -2989999.25

The number on the left is the string I get after tokenizing a bigger
string. The number on the right is the number I get after the conversion.

I've tried two different ways of converting, one way the older C way
using atof, and another more C++ way. Either way, I get the same
result. Can anyone shed some light on this for me?

Here's the code:

string token;
string tokens;
stringstream iss;
getline(fin,bfr);
while (getline(fin, bfr))
{
iss << bfr;
i = 0;
while (getline(iss, token, ','))
{
tokens[i++] = token;
}

std::istringstream b(tokens);
b >price;

//price = atof(tokens.c_str());

I don't think conversion is your problem, I think its your method of
outputting your numbers that is causing rounding and confusion...
JMO.

Jun 7 '07 #3
I used the following code to verify if it was display issue or an actual
conversion issue:

if (price == 2989999.13)
cout << "Match" << endl;

And match was not displayed, so it looks like the conversion is getting
screwed up somehow.

Hank Stalica wrote:
I'm having this weird problem where my code does the following
conversion from string to float:

27000000.0 -27000000.00
2973999.99 -29740000.00
2989999.13 -2989999.25

The number on the left is the string I get after tokenizing a bigger
string. The number on the right is the number I get after the conversion.

I've tried two different ways of converting, one way the older C way
using atof, and another more C++ way. Either way, I get the same
result. Can anyone shed some light on this for me?

Here's the code:

string token;
string tokens;
stringstream iss;
getline(fin,bfr);
while (getline(fin, bfr))
{
iss << bfr;
i = 0;
while (getline(iss, token, ','))
{
tokens[i++] = token;
}

std::istringstream b(tokens);
b >price;

//price = atof(tokens.c_str());
Jun 7 '07 #4
Hank Stalica wrote:
I'm having this weird problem where my code does the following
conversion from string to float:

27000000.0 -27000000.00
2973999.99 -29740000.00
Is this correct, or is it an extra 0?
2989999.13 -2989999.25
This sounds reasonable. If you know how a float looks like in your memory,
you'd expect this too.
The number on the left is the string I get after tokenizing a bigger
string. The number on the right is the number I get after the conversion.

I've tried two different ways of converting, one way the older C way
using atof, and another more C++ way. Either way, I get the same
result. Can anyone shed some light on this for me?
A float can't just store any number you put in. A float has a limited number
of precise digits. What you see is rounding errors.

#include <iostream>
#include <limits>

int main() {
std::cout << std::numeric_limits<float>::digits10 << "\n";
}

On my machine, this program outputs the number 6, indicating that a float
can store six decimal digits precisely. Your numbers have (except for the
first) more than six decimal digits. The indication is often a little low,
because computers don't use the decimal system.
Here's the code:

string token;
string tokens;
stringstream iss;
getline(fin,bfr);
while (getline(fin, bfr))
{
iss << bfr;
i = 0;
while (getline(iss, token, ','))
{
tokens[i++] = token;
}

std::istringstream b(tokens);
b >price;

//price = atof(tokens.c_str());
Don't expect floats or doubles to be accurate. And following: Never use
floats or doubles for prices.

--
Robert Bauck Hamar
Jun 7 '07 #5
Did a little bit of unit testing with the following code and got the
same result:

#include <iostream>
using std::cout;
using std::cin;

int main()
{
char s1[] = "2989999.13";
float f = atof(s1);
printf("%12.2f",f);

if (f == 2989999.13)
cout << "Matches";

return 0;
}

It's converting 2989999.13 to 2989999.25.
What's going on?

Hank Stalica wrote:
I'm having this weird problem where my code does the following
conversion from string to float:

27000000.0 -27000000.00
2973999.99 -29740000.00
2989999.13 -2989999.25

The number on the left is the string I get after tokenizing a bigger
string. The number on the right is the number I get after the conversion.

I've tried two different ways of converting, one way the older C way
using atof, and another more C++ way. Either way, I get the same
result. Can anyone shed some light on this for me?

Here's the code:

string token;
string tokens;
stringstream iss;
getline(fin,bfr);
while (getline(fin, bfr))
{
iss << bfr;
i = 0;
while (getline(iss, token, ','))
{
tokens[i++] = token;
}

std::istringstream b(tokens);
b >price;

//price = atof(tokens.c_str());
Jun 7 '07 #6
Ok, that makes sense.
So I should store the value as two ints? One for the whole number and
one for the fractional amount?

Robert Bauck Hamar wrote:
Hank Stalica wrote:
>I'm having this weird problem where my code does the following
conversion from string to float:

27000000.0 -27000000.00
2973999.99 -29740000.00

Is this correct, or is it an extra 0?
>2989999.13 -2989999.25

This sounds reasonable. If you know how a float looks like in your memory,
you'd expect this too.
>The number on the left is the string I get after tokenizing a bigger
string. The number on the right is the number I get after the conversion.

I've tried two different ways of converting, one way the older C way
using atof, and another more C++ way. Either way, I get the same
result. Can anyone shed some light on this for me?

A float can't just store any number you put in. A float has a limited number
of precise digits. What you see is rounding errors.

#include <iostream>
#include <limits>

int main() {
std::cout << std::numeric_limits<float>::digits10 << "\n";
}

On my machine, this program outputs the number 6, indicating that a float
can store six decimal digits precisely. Your numbers have (except for the
first) more than six decimal digits. The indication is often a little low,
because computers don't use the decimal system.
>Here's the code:

string token;
string tokens;
stringstream iss;
getline(fin,bfr);
while (getline(fin, bfr))
{
iss << bfr;
i = 0;
while (getline(iss, token, ','))
{
tokens[i++] = token;
}

std::istringstream b(tokens);
b >price;

//price = atof(tokens.c_str());

Don't expect floats or doubles to be accurate. And following: Never use
floats or doubles for prices.
Jun 7 '07 #7
Hank Stalica wrote:
Ok, that makes sense.
So I should store the value as two ints? One for the whole number and
one for the fractional amount?
Depends on what you need. If the fractional part is always a fixed number of
integers, you only need one integer. Just place the decimal separator when
printing and check it on input. Before you pick that solution, you should
assert that integers are big enough for your task. If not, you could use a
library. GMP might suit your needs <URL:http://gmplib.org/>

By the way: When following up, try to insert your text below the relevant
parts in the previous post. Then delete unrelevant parts.
Robert Bauck Hamar wrote:
>A float can't just store any number you put in. A float has a limited
number of precise digits. What you see is rounding errors.
--
Robert Bauck Hamar

Jun 7 '07 #8
Hank Stalica wrote:
Could be.
Please don't top-post. Your replies belong following or interspersed
with properly trimmed quotes. See the majority of other posts in the
newsgroup, or the group FAQ list:
<http://www.parashift.com/c++-faq-lite/how-to-post.html>
Jun 7 '07 #9
Hank,
Please don't top-post in this newsgroup. Your responses belong
interspersed with appropriately trimmed quotes. I have fixed it below.

Hank Stalica <us**@example.netwrote:
Hank Stalica wrote:
>I'm having this weird problem where my code does the following
conversion from string to float:

27000000.0 -27000000.00
2973999.99 -29740000.00
2989999.13 -2989999.25

The number on the left is the string I get after tokenizing a bigger
string. The number on the right is the number I get after the conversion.

Did a little bit of unit testing with the following code and got the
same result:
[code snipped]
>
It's converting 2989999.13 to 2989999.25.
What's going on?
See this entry in the FAQ (and also the surrounding ones):

[29.16] Why is floating point so inaccurate? Why doesn't this print 0.43?
http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.16

Also, you should read this paper by David Goldberg when you have the
time (links given at the end of FAQ #29.17):

What Every Computer Scientist Should Know About Floating-Point Arithmetic

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
Jun 7 '07 #10
Thanks for the help, everyone and my apologies for top posting.

I decided to split the float up into two integers and it seems to be
working.

Best Regards,
--Hank Stalica
Jun 8 '07 #11

### This discussion thread is closed

Replies have been disabled for this discussion.

### Similar topics

 2 posts views Thread by Ikot | last post: by 15 posts views Thread by Bushido Hacks | last post: by 1 post views Thread by Meya-awe | last post: by 3 posts views Thread by dean.elwood | last post: by 8 posts views Thread by SpreadTooThin | last post: by 3 posts views Thread by pipe.jack | last post: by 3 posts views Thread by psbasha | last post: by 7 posts views Thread by DirtyRasa | last post: by 7 posts views Thread by ma740988 | last post: by 1 post views Thread by Yacine Si Tayeb | last post: by reply views Thread by XIAOLAOHU | last post: by reply views Thread by RamLakshmanan | last post: by reply views Thread by Yacine Si Tayeb | last post: by reply views Thread by sheikhsab | last post: by 3 posts views Thread by Curious27 | last post: by 4 posts views Thread by MNewby | last post: by 2 posts views Thread by Usman55 | last post: by 1 post views Thread by DJRhino1175 | last post: by