views:

207

answers:

4

hi i read the file as follows

       fscanf(fp,"%f %f %f\n",&*(p1+i), &*(p2+i), &*(p3+i));

my file's lines consists of three floating point numbers...

the problem i have is that in the file let's say i have some floating points with let's say maximum of two digits after the dot. but when i ask c to print those values using different formatting, for example %lf,%.2lf,%.4lf... it starts to play with the digits... my only concern is this, if i have let's say 1343.23 in the file, then will c use this value exactly as it is in computations or it will play with the digits after the dot. if it will play, then how is it possible to make it so that it uses floating point numbers exactly as they are? for example in last case even if i ask it to print that value using %.10lf i would expect it to print only 1343.2300000000.? thanks a lot!

A: 

The number of digits after the dot does not make any difference to fscanf. You should get rid of the &* thing and add a new line to the end of the string:

fscanf(fp, "%f %f %f\n", p1 + i, p2 + i, p3 + i);
Tuomas Pelkonen
+1  A: 

When you read in the string 1343.23, considering it to be a decimal number, it is converted to the computer's internal binary representation. Outputting with a format specifier converts from binary to decimal. On output, if you ask for a different number of digits after the decimal point, you may not get exactly the same value. A particular floating point decimal number may not be exactly representable in a finite-length binary floating point number, so rounding should be expected.

For a better explanation, see the famous article "What Every Scientist Should Know About Floating-Point Arithmetic" -- http://docs.sun.com/app/docs/doc/800-7895

M. S. B.
can i be at least sure for 100% that it will use exactly 1343.23000000000 in computations? or at least how can i force it to use it exactly as 1343.230000 in computations?
mongoose
With normal binary floating-point numbers, you can't. Your decimal value (e.g., 1342.23) may not be representable as a binary floating-point number. If you must have perfect accuracy (e.g., financial computations), then use integers, or use a library for decimal arithmetic.
M. S. B.
@mongoose. There are infinitely many real numbers between (let's say) 0 and 1. You only have a finite number of bits available in a floating-point number. So by simple logic, you can't represent all the real numbers with any representation using finite number of bits. You really should read the linked document.
Alok
@mongoose: The decimal number 1342.23 *has* no finite, exact representation when written as a binary expansion - this is exactly analagous to the way in which you can't exactly represent the number 1/3 as a finite, exact decimal expansion.
caf
+2  A: 

The "problem" is that floating point numbers are by definition, approximate. You should read What Every Computer Scientist Should Know About Floating-Point Arithmetic for more information.

Also, you can simplify &*(x) to x, so you should write p1+i, p2+i, p3+i in your fscanf call.

Alok
That's a good link but floating point numbers are *not* approximate by definition. It's true that you cannot represent every floating point number in a range (because there's an infinite number of them) but there's nothing at all approximate with 1/2 or 1/4 or 1/64.
paxdiablo
@paxdiablo: given a real-floating `x`, of course it represents an exact number. But then, `x` also represents infinitely many real numbers in the range (let's say) `0.5*(x + nextafter(x, -infinity))` to `0.5*(x + nextafter(x, infinity))`. I concede that there are two different ways of thinking here - one way would be to take any floating point number as representing a range, and another would be to take it to represent exact number. There was a long thread on comp.lang.c 5 years ago with good arguments: http://groups.google.com/group/comp.lang.c/msg/beacbe60f477d2f2
Alok
Point taken, @Alok, your viewpoint of seeing a number as a range is certainly valid. +1.
paxdiablo
A: 

May scan by string.

Large floating point number scan by string example:

  char str1[100], str2[100];
  fscanf(file, "%[0-9].%[0-9]", str1, str2);
  fprintf(file, "The number: %s.%s\n", str1, str2);
gmunkhbaatarmn