Precision Issue with STRTOF

M

Marcus Jacobs

Dear Group

I am encountering a precision issue while converting a text string to
a float using STRTOF. For example, at times a text string "736.00000"
(quotation marks added) is converted to "736.00001". I have null
terminated the strings. Does anyone know why does this happen and how
specifically to avoid this. This is quite critical to an applicaiton
that I am writing.


Thanks

Marcus D. Jacobs
 
B

Ben Pfaff

I am encountering a precision issue while converting a text string to
a float using STRTOF. For example, at times a text string "736.00000"
(quotation marks added) is converted to "736.00001". I have null
terminated the strings. Does anyone know why does this happen and how
specifically to avoid this. This is quite critical to an applicaiton
that I am writing.

You should read the FAQ.
 
T

Tom Zych

Marcus said:
I am encountering a precision issue while converting a text string to
a float using STRTOF. For example, at times a text string "736.00000"
(quotation marks added) is converted to "736.00001". I have null
terminated the strings. Does anyone know why does this happen and how
specifically to avoid this. This is quite critical to an applicaiton
that I am writing.

Did you try writing a little test program like this (not tested)?

#include <stdio.h>
main() {
float x = 736.0;
printf("%f\n", (double) x);
}

You'll probably get similar results. Float is the low-precision
type. Double is the high-precision type. Use double.
 
M

Martin Ambuhl

Marcus said:
Dear Group

I am encountering a precision issue while converting a text string to
a float using STRTOF. For example, at times a text string "736.00000"
(quotation marks added) is converted to "736.00001". I have null
terminated the strings. Does anyone know why does this happen and how
specifically to avoid this. This is quite critical to an applicaiton
that I am writing.

Note that C is case-sensitive. The function's name is 'strtof', not 'STRTOF'.
strtof() returns a float. A float need not have more than 6 digits of
precision. The value you report "736.00001" has some 27 bits of information
apart from scaling ("mantissa"). How do you know that the value has those
8 decimal digits of precision? If you would restrict yourself to printing
only the information in the data, you would do better.

#include <stdio.h>
#include <math.h>
void showfloat(x)
{
printf("%.*g", FLT_DIG, x);
}
 
M

Malcolm

Marcus Jacobs said:
I am encountering a precision issue while converting a text string to
a float using STRTOF. For example, at times a text string "736.00000"
(quotation marks added) is converted to "736.00001". I have null
terminated the strings. Does anyone know why does this happen and
how specifically to avoid this. This is quite critical to an applicaiton
that I am writing.
Regard floating point variables as having a small random error. It's not
really random, of course, but there is no exact representation of 0.1 in a
typical floating-point format.

If the the problem is critical to your application, there are several things
you can do. The best and probably easiest is to rewrite your algorithms so
that they can tolerate small errors.

The next thing to do is to use a fixed-point representation. If you only
need three digits of decimal places, you could store all results in longs as
value *1000 (this method is very useful if the values you are dealing with
are currency).

As a last resort, resign yourself to operating in decimal and write your own
floating point routines, maybe taking their operands as ASCII strings. This
will be slow and messy but should be perfectly accurate.
 
T

Tom Zych

Malcolm said:
As a last resort, resign yourself to operating in decimal and write your own
floating point routines, maybe taking their operands as ASCII strings. This
will be slow and messy but should be perfectly accurate.

If someone really needs more precision than double (including exact
fractions), I'd recommend gmp.

http://www.swox.com/gmp/
 
P

pete

Tom said:
Did you try writing a little test program like this (not tested)?

#include <stdio.h>
main() {
float x = 736.0;
printf("%f\n", (double) x);
}

You'll probably get similar results. Float is the low-precision
type. Double is the high-precision type. Use double.


double, is what you should use most of the time
for foating point variables.
float, is for when memory is tight.
long double, is for when double isn't precise enough.
 
T

Tom Zych

pete said:
double, is what you should use most of the time
for foating point variables.
float, is for when memory is tight.
long double, is for when double isn't precise enough.

Some C programmer I am...I forgot all about long double :)
 
J

Jack Klein

double, is what you should use most of the time
for foating point variables.
float, is for when memory is tight.
long double, is for when double isn't precise enough.

....assuming that there are actually three different underlying
representations, which there most certainly not on a lot of platforms.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
 
J

Joe Wright

Marcus said:
Dear Group

I am encountering a precision issue while converting a text string to
a float using STRTOF. For example, at times a text string "736.00000"
(quotation marks added) is converted to "736.00001". I have null
terminated the strings. Does anyone know why does this happen and how
specifically to avoid this. This is quite critical to an applicaiton
that I am writing.

Thanks

Marcus D. Jacobs

You've gotten quite a few interesting responses by now but none of them
see the 'error' in your post. A float or a double can represent integers
precisely (without error) up to 2**24 for float and 2**53 for double.
The case for "736.00000" converting to "736.00001" would indicate an
error in strtof() perhaps. The floating point representation of 736 is
exact, not an approximation.
 
M

Martin Ambuhl

Joe Wright wrote:

You've gotten quite a few interesting responses by now but none of them
see the 'error' in your post. A float or a double can represent integers
precisely (without error) up to 2**24 for float and 2**53 for double.

uh-uh. A float must be accurate to 6 decimal digits (about 20 bits) and a
double to 10 decimal digits (about 33 bits). Your implementation does not
define the language.
The case for "736.00000" converting to "736.00001" would indicate an
error in strtof() perhaps.

uh-uh. It shows that he was trying to get 8 digits printed from a variable
for which only 6 are required. This is a *programmer* error in misusing
?printf().
 
L

LibraryUser

Ben said:
You should read the FAQ.

However, assuming the OP really means strtof(), it seems to be an
extremely poor implementation that cannot maintain exact values
for a range of integers that fit in the significand. Maybe
Marcus should identify it, so that we can avoid it.

In general float (or double, etc.) values should never be tested
for exact equality. They are always the 'best' approximation to
the value that the implementation can provide. They should
always meet the criteria specified by FLT_EPSILON.
 

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

Members online

Forum statistics

Threads
474,079
Messages
2,570,573
Members
47,205
Latest member
ElwoodDurh

Latest Threads

Top