Garbage data in float datatype - Mingw3.2 (gcc)

  • Thread starter Gerald Lafreniere
  • Start date
G

Gerald Lafreniere

{
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])

Gerald Lafreniere
(e-mail address removed)
 
E

Eric Sosman

Gerald said:
{
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])

This is Question 14.1 in the comp.lang.c Frequently
Asked Questions (FAQ) list

http://www.eskimo.com/~scs/C-faq/top.html

Perhaps we should petition the FAQ maintainer to renumber
it to "Question 14.100000381" ...
 
G

Gerald Lafreniere

Thanks,

I never knew about this faq.
I just learnt something new today.

Gerald Lafreniere
(e-mail address removed)


Eric Sosman said:
Gerald said:
{
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])

This is Question 14.1 in the comp.lang.c Frequently
Asked Questions (FAQ) list

http://www.eskimo.com/~scs/C-faq/top.html

Perhaps we should petition the FAQ maintainer to renumber
it to "Question 14.100000381" ...
 
C

Chris Croughton

{
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
 
C

CBFalconer

Gerald said:
Eric Sosman said:
Gerald said:
{
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])

This is Question 14.1 in the comp.lang.c Frequently
Asked Questions (FAQ) list

http://www.eskimo.com/~scs/C-faq/top.html

Perhaps we should petition the FAQ maintainer to renumber
it to "Question 14.100000381" ...

I never knew about this faq.
I just learnt something new today.

Good. Now you should learn not to top-post (which I corrected
here). Your answer belongs after, or intermixed with, the material
to which you are responding, with anything immaterial to your reply
snipped out. The snippage is also important.
 
F

Frank Schmied

{
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])

This is not primarily "garbage" but "loss of precision". Ok, of
course, it *is* garbage, but one that can be predicted.
float stores floating point data in 4 bytes and is splitted into a
"mantissa"- and an "exponent"-part: 0.123456 * 10^3

In some cases, the mantissa has not enough space, to precisely encode
the number. This is because of the internal representation of the
number in the mantissa (the number is stored as a sum of 2^-x).

Manipulations to the number (ie. "calculations") cause the error to
show up or aggravate.

In your case, switching to a floating point data type with a higher
precision (double) or to BCD-float-arithmetic could help.
--
,,,
_ _ \(((.
__,,../v\,----../ `-..=.>"" _\,_
_______;/____<_ \_______\ \___////______;[email protected]_______
,"/ `.) `.) ```
/," /7__ /7_
(( ' \\\ )))
)
/
 
C

CBFalconer

Frank said:
{
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])

This is not primarily "garbage" but "loss of precision". Ok, of
course, it *is* garbage, but one that can be predicted.
float stores floating point data in 4 bytes and is splitted into
a "mantissa"- and an "exponent"-part: 0.123456 * 10^3
^^^^^^^^^^
The correct word is "significand". Mantissas are part of
logarithms. The size is also specified by sizeof(float), and has
no need to be 4. See <float.h> for details on your particular
system.
 
G

Gerald Lafreniere

Thanks for the advice.

I was trying to automatically determine the precision of a decimal number.
I can do it with whole numbers, but once the decimal kicks in, it just
doesn't work properly(because of the garbage).

for ( precision=0, F-=(float) ( (int) F ); F!=0; ++precision, F*=10,
F-=(float) ( (int) F ) );

My work around will be to just specify the precision.

Gerald Lafreniere
(e-mail address removed)
 
K

Keith Thompson

Gerald Lafreniere said:
/me salutes his furer

Insulting people who give you good advice is an effective way to get
yourself into a lot of people's killfiles.
 
C

CBFalconer

Gerald said:
I was trying to automatically determine the precision of a decimal
number. I can do it with whole numbers, but once the decimal kicks
in, it just doesn't work properly(because of the garbage).

for ( precision=0, F-=(float) ( (int) F ); F!=0; ++precision, F*=10,
F-=(float) ( (int) F ) );

My work around will be to just specify the precision.

<float.h> has all that information for your system.
 
G

Gerald Lafreniere

I like advice, but outright telling what to do in a condescending way, and
as if your the boss(when you're not!), puts you in bad terms with me.

If you're going to push etiquette, then you should at least be polite about
it and ask someone to do something, instead of telling them to do it,
otherwise you're what I call a hypocrite.

Gerald Lafreniere
(e-mail address removed)
 
G

Gerald Lafreniere

Thanks for all the good advice and good information, I learnt a lot here,
and I'm gr8full.
 
I

infobahn

Gerald said:
I like advice, but outright telling what to do in a condescending way, and
as if your the boss(when you're not!), puts you in bad terms with me.

The lack of context here is a problem. I haven't seen the article that
prompted this reply (yet), because it hasn't reached my server. I have
no idea who you're talking about or why. If you're going to fight in
public, you might at least indicate with whom you are fighting and
why. Leaving relevant context in your article as a quote allows that.

Better still, in future, please fight your good fight in
email! Thanks. :)
 
K

Keith Thompson

Gerald Lafreniere said:
Thanks for all the good advice and good information, I learnt a lot here,
and I'm gr8full.

Glad to hear it.

Here's some more advice for you. You should provide some context when
you post a followup. The format for doing so is fairly simple.

I also advise you not to take things too personally. If someone
doesn't phrase his advice in the way you like, publicly insulting them
is not an appropriate response.
 
C

CBFalconer

infobahn said:
The lack of context here is a problem. I haven't seen the article
that prompted this reply (yet), because it hasn't reached my server.
I have no idea who you're talking about or why. If you're going to
fight in public, you might at least indicate with whom you are
fighting and why. Leaving relevant context in your article as a
quote allows that.

Better still, in future, please fight your good fight in
email! Thanks. :)

I believe he got his water hot over this rude response of mine:
Good. Now you should learn not to top-post (which I corrected
here). Your answer belongs after, or intermixed with, the material
to which you are responding, with anything immaterial to your reply
snipped out. The snippage is also important.
.... snip ...
 
S

spingoogL

Keith said:
Glad to hear it.

Here's some more advice for you. You should provide some context when
you post a followup. The format for doing so is fairly simple.

I also advise you not to take things too personally. If someone
doesn't phrase his advice in the way you like, publicly insulting them
is not an appropriate response.

Yeh, I know, I got a little heated about that, and I apologize.
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top