Sign in to follow this  
Daishim

atof() precision

Recommended Posts

I'm running into a problem with atof() that is as follows. I am using strtok() to seperate 3 floating point values in a string delimited by a space. When I plug the values into atof(), I get a value that is slightly off from the value passed in. For example, if I pass in a string that contains "-0.384499" atof returns "-0.38449901" when casted to a float and "-0.38449899999999998" as an unchanged double. Is there something goofy with the MS atof() function or am I overlooking something?

Share this post


Link to post
Share on other sites
I know its not what you're looking for, but have you tried to use something like sscanf instead?

Edit: or even strtod()? I'm also pretty sure boost has something to handle convertions

Hope this helps

Share this post


Link to post
Share on other sites
Everything is in C++, so I'm trying to avoid using scanf() if possible, but if I can't figure out what the deal is with atof(), then I just might have to resort to it.

Share this post


Link to post
Share on other sites
You might wanna look into

float f;
std::string s;

f = boost::lexical_cast<float>(s);
s = boost::lexical_cast<std::string>(f);

(boost is available at www.boost.org)

Share this post


Link to post
Share on other sites
I am using ifstream to buffer the entire file into a string, becuase I need to make multiple passes through the file data. I then use istringstream to retrieve data line by line. I then dump the string floating point values into atof(), which is where the problem lies.

Share this post


Link to post
Share on other sites
If your already using stringsreams I don't understand why you want to use atof


#include <stream>
#include <sstream>

int main(int,char**){
char const szFloat[]="1.2234";
char const szFloat2[] = "112.5";
std::stringstream convert;
float fval;

convert << szFloat;
convert >> fval;

std::cout << fval << std::endl;

// must clear the state prior to using insertion operator again
// you need to do this each time after you've switched between
// insertion and extraction operators
convert.clear( );
// I'm also going to empty the character stream
convert.str("");

convert << szFloat2;
convert >> fval;

std::cout << fval << std::endl;

return 0;
}


[edit]
But if you don't want to switch to using the pure C++ way - I guess you could search on the internet for ways of setting the floating point precision for the C runtime library. I don't know if its possible off the top of my head, but that seems to be the issue your fighting against.

Share this post


Link to post
Share on other sites
The numbers you posted simply cannot be represented by floats or doubles. It has nothing to do with atof.

Share this post


Link to post
Share on other sites
Doubles don't have infinite precision. Doubles are binary, not decimal. These two facts make them generally incapable of exactly representing most things that have a finite number of decimal digits.

Share this post


Link to post
Share on other sites
Quote:
Original post by Puzzler183
Doubles don't have infinite precision. Doubles are binary, not decimal. These two facts make them generally incapable of exactly representing most things that have a finite number of decimal digits.


Yes, this I understand. However, I was under the assumption that these values were once represented in a binary fashion, since they are an export from a modeling program. However, after closer inspection, these numbers cannot be represented exactly in float/double form. So it's back to the drawing board on this one.

Share this post


Link to post
Share on other sites
Quote:
Original post by Puzzler183...However, I was under the assumption that these values were once represented in a binary fashion, since they are an export from a modeling program.


They are most likely truncated upon export, this is very common.

Share this post


Link to post
Share on other sites
Quote:
Original post by Daishim
Quote:
Original post by Puzzler183
Doubles don't have infinite precision. Doubles are binary, not decimal. These two facts make them generally incapable of exactly representing most things that have a finite number of decimal digits.


Yes, this I understand. However, I was under the assumption that these values were once represented in a binary fashion, since they are an export from a modeling program.


Your exporter did not output enough digits to represent the value exactly. That is why when you convert back to float, you get a slightly different number. That is probably unimportant detail, because the original value before exporting is very close to -0.384499 (maybe -0.38449901 or -0.38449899999999998), so you end up getting the original number anyway (or something close enough).

In the end, you can't represent decimal fractions exactly, so unless 6 digits of precision is not good enough, there is nothing to worry about.

Share this post


Link to post
Share on other sites
I'm not actually doing the exporting. I'm reading the data in from a wavefront OBJ file for a free example model. However, Maya is able to load the model, from the OBJ, without problems and all the edges are perfectly aligned.

Share this post


Link to post
Share on other sites
If it looks fine in maya but not in your program then the problem is not with the precision. Both programs will get the same values from reading the file, so both will lose the same negligible amount of precision.
It may be doing things like merging points that compare are not equal, but very close to equal, as is commonly done. Or it may be nicely dectecing T-section join cases and re-triangulating etc to perfectly remove any seams.

So in summary, maya is something else that you are not doing, or are doing incorrectly, that is causing you grief. It is not the accuracy of a float/double itself, or the fact that it is being converted from text incorrectly.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this