Click here to Skip to main content
15,885,716 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Hello All,

I have an application that allows the user to input floating point values. These values are read into a CString and then converted to a floating point integer to be stored into a file. Everything went great until I started tested the input data. Any number that had a .1, .4, .6, .9 was converted incorrectly.

I first used atof(). Then I tried scanf(). And sscanf() and got the same issues.

I even wrote a little routine to parse through the string, pluck the whole number and fraction. I noticed when dividing and casting floats I got the same issue! For example if you have a number say 15 that is really .15 and you divide it by 100 you get .1500001.

I saw some example where mod() and pow() were used to round the number. However, I don’t know what the rounding will be since the inputs can range from (99 to .000013).

I guess my question at hand is "is there a way to add a precision argument for an atof() or scanf() similar to printf(str,"%3.5f",data);"?

Best regards,
Posted
Updated 20-Jan-10 12:10pm
v2

Hello,

as the other answers say, it's a matter of the kind how floating point values are stored.

atof() is the better choice. It should be declared as double atof( const char *string );. Use a double variable instead of a float and you will have a precision that is enough for your range of 99 to 0.000013. Then, when you use the correct format string for printf() the values are printed correct, rounded to the number of digits you defined in the format string.

Take care on the format string, the first number is the over all length of the output, use "%9.6f" for the same length on all outputs.

Another point is, take care on comparing floating point values.

This comparison may fail, because the result of atof() is .1500001 what is not the same as .15!
double dValue = atof( strInput);
if( .15 == dValue)
{
}


Instead use somthing like this:
double dValue = atof( strInput);
if( fabs( .15 - dValue) < 0.01)
{
}

The comparison value (0.01) depends on the tolerance you can accept.

Best regards
 
Share this answer
 
All digital computers that I am familiar with are binary. The results you got are not what you expected or wanted, but are correct. When you are working with floats and doubles, you should generally consider that you are working with approximations. Machine representations of numbers and machine arithmetic aren't quite the same as the real thing.

In base 10 you cannot write 1/3 exactly in the form of a terminating decimal fraction. In the same way, you cannot write any fraction with a denominator that is not a power of 2 exactly in the form of a terminating binary point fraction. There are also other artifacts involved in working with binary machine floating point numbers.

If the artifacts of machine floating point arithmetic are not acceptable in your application, then you will have to use something other than floats or doubles.

One alternative might be to use scaled integers. Another is to use an arbitrary precision math package of some type.

What to use depends on the situation you are dealing with and what matches up best with the different ways of representing numbers with a machine.
 
Share this answer
 
v3
Floats have about 6 digits of precision. However, they are stored similar to scientific notation. It stores a number along with a magnitude to set where in that number the decimal point should appear. For example, you could have the number 654321 and then adjust it by placing the decimal point in the middle (654.321), before the beginning (0.000000654321), or after the end (654321000000). However, you only get about 6 digits to store the precision of that number. If you want more precision, you can use a double instead of a float. Doubles have about 15 digits of precision. For more information, see this.

As the other answer said, you can use a library that stores numbers as fractions. That way, you can have virtually unlimited precision. Just keep in mind that these numbers take up more memory and are slow to use. You'll have to do some searching, but here are some starting points so you know what to look for: an extended decimal class, and a fractional numbers class.
 
Share this answer
 
Once you do math, the results will be inconsistent. There's an article about it here on Codeproject.

Reliable Floating Point Equality Comparison[^]

If the language you're using has a decimal type, use it instead of floats/doubles, because using a decimal type for math that could result in "floating point" values retains its accuracy. It's a little slower, but if accuracy is "your thing", it's a better choice.
 
Share this answer
 
v3

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900