By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,836 Members | 1,922 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,836 IT Pros & Developers. It's quick & easy.

what is happening in C when increment this way?

P: n/a
If you run this program, it will give very unexpected results. Can
anyone explain the nature of this anamaly? (also what is the function
call [and library to include linux/windows] to execute 'pause');

#include<stdio.h>

//void pause(){ unsigned long i=0; while(i++<10000000); }

int main(){
float i;

for(i=0;i<100;i+=0.1) // pay attention
{ // pause();
printf("%d\n",i);
}

printf("\n");
return 0;
}

Nov 14 '05 #1
Share this Question
Share on Google+
13 Replies


P: n/a

puzzlecracker wrote:
If you run this program, it will give very unexpected results. Can
anyone explain the nature of this anamaly? (also what is the function
call [and library to include linux/windows] to execute 'pause');

#include<stdio.h>
int main(){
float i;

for(i=0;i<100;i+=0.1) // pay attention
{ // pause();
printf("%d\n",i);
Use %f instead of %d (%d is to be used only for decimal integers).
You're getting weird results by invoking undefined behaviour
(conversion specified mismatch with corresponding argument). }

printf("\n");
return 0;
}


Nov 14 '05 #2

P: n/a
puzzlecracker wrote:
If you run this program, it will give very unexpected results. Can
anyone explain the nature of this anamaly? (also what is the function
call [and library to include linux/windows] to execute 'pause');

printf("%d\n",i);


This line is the problem. The format specifier for printifng floats
(and doubles) is %f (or %e or %g).

--John
Nov 14 '05 #3

P: n/a

John Valko wrote:
puzzlecracker wrote:
If you run this program, it will give very unexpected results. Can
anyone explain the nature of this anamaly? (also what is the function call [and library to include linux/windows] to execute 'pause');

printf("%d\n",i);


This line is the problem. The format specifier for printifng floats
(and doubles) is %f (or %e or %g).

--John

I mean %f actually ---- it does print but it gets weirder
try it withj %f

Nov 14 '05 #4

P: n/a
puzzlecracker wrote:
John Valko wrote:

This line is the problem. The format specifier for printifng floats
(and doubles) is %f (or %e or %g).

--John


I mean %f actually ---- it does print but it gets weirder
try it withj %f


Please explain what you mean by "weirder"
Nov 14 '05 #5

P: n/a

John Valko wrote:
puzzlecracker wrote:
John Valko wrote:

This line is the problem. The format specifier for printifng floats(and doubles) is %f (or %e or %g).

--John


I mean %f actually ---- it does print but it gets weirder
try it withj %f


Please explain what you mean by "weirder"


run the program and tell me if output was expected. I traced the
problem but cannot yet explain it. IT has to do with the way floating
point numbers are represented.

Nov 14 '05 #6

P: n/a
puzzlecracker wrote:
If you run this program, it will give very unexpected results.
1) There is nothing unexpected about using the wrong (integer) specifier
to output floating point values.
2) There is nothing unexpected about the results of using loops with
floating point counters with inexact increments.

Unpredictable across platforms, yes, but not unexpected.
Can
anyone explain the nature of this anamaly?
1) Anyone who can read the documentation (or a basic C text) for printf can.
2) Anyone who knows anything about floating point representation can.

There are some questions in the FAQ relating to your question.
See, for example
<http://www.eskimo.com/~scs/C-faq/q14.4.html>.
Always check the FAQ before posting. Haven't you been told this before?
I applaud your attempt to expand your vocabulary, but the word is "anomaly."
(also what is the function
call [and library to include linux/windows] to execute 'pause'); It is system-specific.

#include<stdio.h>

//void pause(){ unsigned long i=0; while(i++<10000000); }

int main(){
float i;

for(i=0;i<100;i+=0.1) // pay attention
{ // pause();
printf("%d\n",i);
}

printf("\n");
return 0;
}

Nov 14 '05 #7

P: n/a

Martin Ambuhl wrote:
puzzlecracker wrote:
If you run this program, it will give very unexpected results.
1) There is nothing unexpected about using the wrong (integer)

specifier to output floating point values.
2) There is nothing unexpected about the results of using loops with
floating point counters with inexact increments.

Unpredictable across platforms, yes, but not unexpected.
Can
anyone explain the nature of this anamaly?
1) Anyone who can read the documentation (or a basic C text) for

printf can. 2) Anyone who knows anything about floating point representation can.

There are some questions in the FAQ relating to your question.
See, for example
<http://www.eskimo.com/~scs/C-faq/q14.4.html>.
Always check the FAQ before posting. Haven't you been told this before? I applaud your attempt to expand your vocabulary, but the word is "anomaly."
(also what is the function
call [and library to include linux/windows] to execute 'pause');

It is system-specific.

#include<stdio.h>

//void pause(){ unsigned long i=0; while(i++<10000000); }

int main(){
float i;

for(i=0;i<100;i+=0.1) // pay attention
{ // pause();
printf("%d\n",i);
}

printf("\n");
return 0;
}


YOU ARE WRONG - it not SYSTEM NOR COMPILER SPECIFIC-- it is the way
floats represented.
same anOmaly is in java as well as C#, c++ I checked
thx for trying though

Nov 14 '05 #8

P: n/a
puzzlecracker <ir*********@gmail.com> wrote:
If you run this program, it will give very unexpected results. Can
anyone explain the nature of this anamaly? (also what is the function
call [and library to include linux/windows] to execute 'pause');

float i;

for(i=0;i<100;i+=0.1) // pay attention
{
printf("%d\n",i);
}


Ill ignore the rather obvious printf problem and ask:

How many times are you expecting this loop to execute?

I hope you weren't expecting 1000 times.
The C FAQ, Question 14.1 may give you a clue why:

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

Try also question 14.4

http://www.eskimo.com/~scs/C-faq/q14.4.html
PS: If you post via google, I've heard that groups.google.ca
won't mangle indentation levels.

--
With sufficient thrust, pigs fly just fine. However, this is
not necessarily a good idea. It is hard to be sure where they
are going to land, and it could be dangerous sitting under them
as they fly overhead. -- RFC 1925
Nov 14 '05 #9

P: n/a
puzzlecracker wrote:
Martin Ambuhl wrote:
(also what is the function
call [and library to include linux/windows] to execute 'pause');


It is system-specific.

YOU ARE WRONG - it not SYSTEM NOR COMPILER SPECIFIC-- it is the way
floats represented.


Pardon me for asking, but how long have you been an idiot? The only
reference to "system specific" is the above answer to the above
question, and I never mentioned "compiler specific." Just why do you
think the non-standard function pause() might have anything to do with
the representation of floats?
Nov 14 '05 #10

P: n/a
puzzlecracker wrote:

If you run this program, it will give very unexpected results. Can
anyone explain the nature of this anamaly? (also what is the function
call [and library to include linux/windows] to execute 'pause');

#include<stdio.h>

//void pause(){ unsigned long i=0; while(i++<10000000); }

int main(){
float i;

for(i=0;i<100;i+=0.1) // pay attention
{ // pause();
printf("%d\n",i);
}

printf("\n");
return 0;

}


Don't use C99 comments in C90 code. The result:

[1] c:\c\junk>gcc junk.c
junk.c:3: parse error before '/' token
junk.c: In function `main':
junk.c:8: parse error before '/' token
junk.c:10: warning: int format, double arg (arg 2)
junk.c: At top level:
junk.c:12: parse error before string constant
junk.c:12: warning: type defaults to `int' in declaration of
`printf'
junk.c:12: warning: conflicting types for built-in function
`printf'
junk.c:12: ISO C forbids data definition with no type or storage
class

After removing those execrences we get:

[1] c:\c\junk>gcc junk.c
junk.c: In function `main':
junk.c:8: warning: int format, double arg (arg 2)

and lying to the compiler about the type of an argument to a
variadic function is undefined behaviour.

There is no "pause" function in standard C.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #11

P: n/a
puzzlecracker wrote:
John Valko wrote:
puzzlecracker wrote:
If you run this program, it will give very unexpected results.
Can anyone explain the nature of this anamaly? (also what is the


.... snip ...
I mean %f actually ---- it does print but it gets weirder
try it withj %f


Seems perfectly normal to me. I get:

0.000000
0.100000
..... snip ....
99.799049
99.899048
99.999046

What do you think the exact value of your 0.1 constant really is?
--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #12

P: n/a

What people are trying to say is in floating point
float f;

f= 1.0 + 1.0;

And some how f=1.99999999 (newbie gasp and old timers say So?)
so in floating point 1+1 <>2
The is how floating point math is in all languages on all compilers.
Nov 14 '05 #13

P: n/a
Neil Kurzman wrote:
What people are trying to say is in floating point
float f;

f= 1.0 + 1.0;

And some how f=1.99999999 (newbie gasp and old timers say So?)
so in floating point 1+1 <>2
The is how floating point math is in all languages on all compilers.


You have the right general idea, but unfortunately your example is
completely wrong.

There is some range within which floating point numbers can represent
integers precisely (for float, this will typically be around +/- 2^24).
Outside this range, there will be a gap between one integer and the
next larger one that can be represented. As the magnitude of the number
grows, so does the size of the gap from one number to the next, so the
total number of digits that can be represented remains roughly constant
(the amount of data that can be represented does remain constant, but
the binary to decimal conversion can vary the number of decimal digits
the number converts to, and when you look at it in decimal, you often
get a half digit of precision -- i.e. a final digit that's not
completely right, but not complete wrong either -- e.g if it's a five,
the correct value might really be four or six, but definitely isn't 1
or 9).

Toward the center of the range, (e.g. between -1 and 1) you have more
data available than is necessary to represent an integer. In this case,
some places after the decimal point represent real data.

As soon as we get to fractions, however, we run into another problem:
we're representing the number as a binary fraction. The only fractions
that can be represented precisely are those whose prime factorizations
contain only 2. Otherwise, we end up with a repeating fraction of some
sort that can't be represented precisely in any finite number of bits.

So, 1.0f + 1.0f will always equal exactly 2.0f -- but if you continue
adding 1.0f often enough, you'll reach a point at which it no longer
changes the value of the result AT ALL! For example, a loop like this:

float current = 1.0f, previous = 0.0f;

while (current != previous) {
previous = current;
current += 1.0;
}

will exit in well under a second on a typical machine.

With doubles you get the same basic characteristics, though with a lot
more precision, including a much larger range within which integers can
all be represented precisely.

One other minor detail: by default, C and C++ output functions will
print either a float or a double to the same precision. If memory
serves, the default is 5 digits. More or less by chance, this happens
to be about the limit a typical float can represent, so almost ANY sort
of error in a float will show up immediately.

As mentioned above, a double typically has quite a bit more precsion --
around 15 digits in fact. This means that if you print out with the
default precision, a double will look like it's giving a precisely
correct result until or unless your result has gotten far enough off to
destroy the precision of roughly 2/3rds of its digits.

--
Later,
Jerry.

The universe is a figment of its own imagination.

Nov 14 '05 #14

This discussion thread is closed

Replies have been disabled for this discussion.