質問

I am using a library for loading Wavefront .obj files into my OpenGL application (tinyobjloader). I noticed that there is an error when loading objects. When I load an object with a coordinate of eg. 0.9999999 it is set to 0. By debugging I found out that the following method produces this behaviour:

static inline float parseFloat(const char*& token)
{
    token += strspn(token, " \t");
    float f = (float)atof(token);
    token += strcspn(token, " \t\r");
    return f;
}

So atof() returns somehow an int, not a float. I read that some compilers don't throw a warning when using atof() without including "stdlib.h" and the result is that atof() returns an integer.

The curious thing is that even if I include "stdlib.h" the error remains. I can't figure out what causes this behaviour.

Any idea?

役に立ちましたか?

解決

The standard says to atof:

Except for the behaviour on error, it is equivalent to strtod(nptr,(char**)NULL)

so yours returning '0' has nothing to do with a float not being able to represent it or similar.

Would you use strtod instead (which you probably should when stringstreams are not an option, just to be able to report errors), then you would likely notice that it stops parsing at the ..

This is a strong indication that you are using a locale that awaits , instead of . as s decimal separator. Depending on how your application works with locales, you might want to run it with a properly set environment variable (e.g. LC_NUMERIC=C) or do a setlocale(LC_NUMERIC,"C"); yourself before any parsing.

In any case you should analyze who in your application is using locale dependent things, and what for, so as to not collide with them. Another possible route is to require locale dependent input everywhere, so everyone needs to give the numbers to you with , as decimal separator.

他のヒント

You can see the documentation of atof here . Some Floating points cannot be represented in 32 bits and hence you are getting an error and value returned is zero.

//Try these 
float f = 0.9999999 ;
cout << atof("0.9999999") << " " << f << endl;//output is 1 1 

So what you are seeing is a valid behavior. You may want to try strtod()

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top