On Fri, 07 Jan 2005 19:48:04 GMT, Gerald Lafreniere

<ge***************@apollomachine.com> wrote:

{

float F=123.456000;

F*=1000; // Actually I used a for loop F*=10 three times.

printf("%f\n", F);

}

This will produce something like 123456.00XXXX, where XXXX are garbage

digits. Why is this happening, and how do I get rid of it? (using Dev-C++

with Mingw3.2 [gcc])

A float probably only has 24 bits of mantissa (since you specify the

platform, I'm pretty certain that's what it has). That's only 6 full

digits, which is what are printed correctly. The %f in printf, giving

no precision has a default of 6 characters after the decimal point,

which is why you are seeing those extra digits.

If you used %g, that will trim trailing zeros and defaults to a

precision of 6 digits total, which would represent it as just 123456.

Note that float values passed into printf (and its cousins) are extended

to type double (51 bits of precision on the x86 with gcc), there is no

modifier to say "this was a float value originally (in my opinion an

omission in the spec.). If you need extra precision, you can use type

double instead of float.

See the C specification paragraph 7.19.6.1 (it's actually fprintf there,

but it describes the formats allowed and what they do). Or since you

are running Mingw you may be able to do info gcc and search for printf,

or do man printf, to give you the same information.

If you want to see how many bits are represented by each type, look in

header float.h for your platform. The one on my system define values:

/* Radix of exponent representation */

#define FLT_RADIX 2

/* Number of base-FLT_RADIX digits in the significand of a float */

#define FLT_MANT_DIG 24

/* Number of decimal digits of precision in a float */

#define FLT_DIG 6

/* Addition rounds to 0: zero, 1: nearest, 2: +inf, 3: -inf, -1: unknown */

#define FLT_ROUNDS 1

/* Difference between 1.0 and the minimum float greater than 1.0 */

#define FLT_EPSILON 1.19209290e-07F

/* Minimum int x such that FLT_RADIX**(x-1) is a normalised float */

#define FLT_MIN_EXP (-125)

/* Minimum normalised float */

#define FLT_MIN 1.17549435e-38F

/* Minimum int x such that 10**x is a normalised float */

#define FLT_MIN_10_EXP (-37)

/* Maximum int x such that FLT_RADIX**(x-1) is a representable float */

#define FLT_MAX_EXP 128

/* Maximum float */

#define FLT_MAX 3.40282347e+38F

/* Maximum int x such that 10**x is a representable float */

#define FLT_MAX_10_EXP 38

The same sort of thing with DBL instead of FLT for double variables, and

with LDBL for long double (these are specified -- the macros, not the

precise values -- in the C specification).

The C specification is available to buy from ANSI, go to

http://webstore.ansi.org/ansidocstore
and search for 9899. You probably don't want to buy the ISO version

(US$183 or $278), get the ANSI one for $18 as a PDF. The two Corrigenda

are free (both also PDF). I make a lot of reference to it.

Unfortunately the previous (1989) standard is not available

electronically.

Chris C