Thread: float13

  1. #1
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300

    float13

    i just started using floats. Why does this:

    Code:
    #include <stdio.h>
    
    int main () {
    	int X=1,i;
    	float x;
    	for (i=0;i<20;i++) {
    		x=(float)X/10;
    		printf("%d %f %d\t",X,x,i);
    		x+=0.1f;
    		X=x*10;
    		printf("%d %f \n",X,x);
    	}
    	return 0;			
    }
    do this???:
    Code:
    1 0.100000 0    2 0.200000 
    2 0.200000 1    3 0.300000 
    3 0.300000 2    4 0.400000 
    4 0.400000 3    5 0.500000 
    5 0.500000 4    6 0.600000 
    6 0.600000 5    7 0.700000 
    7 0.700000 6    8 0.800000 
    8 0.800000 7    9 0.900000 
    9 0.900000 8    10 1.000000 
    10 1.000000 9   11 1.100000 
    11 1.100000 10  12 1.200000 
    12 1.200000 11  13 1.300000 
    13 1.300000 12  13 1.400000 
    13 1.300000 13  13 1.400000 
    13 1.300000 14  13 1.400000 
    13 1.300000 15  13 1.400000 
    13 1.300000 16  13 1.400000 
    13 1.300000 17  13 1.400000 
    13 1.300000 18  13 1.400000 
    13 1.300000 19  13 1.400000 
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Try this and expect enlightenment:
    Code:
    #include <stdio.h>
    
    int main () {
    	int X=1,i;
    	float x;
    	for (i=0;i<20;i++) {
    		x=(float)X/10;
    		printf("%d %.10f %d\t",X,x,i);
    		x+=0.1f;
    		X=x*10;
    		printf("%d %.10f \n",X,x);
    	}
    	return 0;			
    }

  3. #3
    Registered User
    Join Date
    Nov 2008
    Posts
    41
    Float representation in a computer is very approximate. When you times 1.400000 by 10 it gets some number which is very close to 14 but is not exactly 14. When you then cast that into an int (which just cuts off everything after the decimal place) it becomes 13 because it is likely something like 13.9977291 or something. Casting from float to int is a tricky one and best avoided unless you know the outcome. Instead just add 1 to X each iteration of the loop.
    Code:
    int main () {
    	int X=1,i;
    	float x;
    	for (i=0;i<20;++i) {
    		x=(float)X/10;
    		printf("&#37;d %f %d\t",X,x,i);
    		x+=0.1f;
    		++X;
    		printf("%d %f \n",X,x);
    	}
    	return 0;			
    }

  4. #4
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    What compiler are you using? Works for me.
    Code:
    [Session started at 2008-12-16 21:19:49 -0600.]
    1 0.100000 0	2 0.200000 
    2 0.200000 1	3 0.300000 
    3 0.300000 2	4 0.400000 
    4 0.400000 3	5 0.500000 
    5 0.500000 4	6 0.600000 
    6 0.600000 5	7 0.700000 
    7 0.700000 6	8 0.800000 
    8 0.800000 7	9 0.900000 
    9 0.900000 8	10 1.000000 
    10 1.000000 9	11 1.100000 
    11 1.100000 10	12 1.200000 
    12 1.200000 11	13 1.300000 
    13 1.300000 12	14 1.400000 
    14 1.400000 13	15 1.500000 
    15 1.500000 14	16 1.600000 
    16 1.600000 15	17 1.700000 
    17 1.700000 16	18 1.800000 
    18 1.800000 17	19 1.900000 
    19 1.900000 18	20 2.000000 
    20 2.000000 19	21 2.100000 
    
    The Debugger has exited with status 0.
    Mainframe assembler programmer by trade. C coder when I can.

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Dino View Post
    What compiler are you using?
    gcc 4.1.2

    I think Noise explained tabstop.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #6
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    I'm running i686-apple-darwin9-gcc-4.0.1.
    Mainframe assembler programmer by trade. C coder when I can.

  7. #7
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    Code:
    X=x*10;
    I don't like the look of that X is an integer and you are assigning it to a float times 10 (I think).

    I also don't like you using X and x, looks confusing.
    I think maybe a float is beinig squashed into the int???
    Dunno I have gcc, maybeI will give it a try!!

    Tried it does same for me!!
    Last edited by esbo; 12-16-2008 at 09:47 PM.

  8. #8
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    Dunno if this is relevant, but maybe it is due to some sort of machine representation
    of numbers. I was curious why the the change/error took place at 13-14.
    Looks like maybe some problem going from base 10 to base 16 if you see what I mean.
    I think if you combine that with say 14 being 13.999 and the fact that you start from zero
    the the change takes place at 16? which is were 0F (hex) changes to 10 (hex).

    Of course I might be talking out of may ass

  9. #9
    Registered User
    Join Date
    Nov 2008
    Posts
    41
    It might work differently for Dino because he's on a different system which represents floats differently and rounded 1.400000 * 10 to something slightly greater than 14 instead of slightly less than.

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by esbo View Post
    Of course I might be talking out of may ass
    We take that for granted.

    But yes, the number is stored internally in binary, and 1/10 can not be represented exactly in binary. But hex is not involved in any way.

  11. #11
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    Maybe MK27 has one of those "special edition" floating point chips from a few years back.
    Mainframe assembler programmer by trade. C coder when I can.

  12. #12
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    Quote Originally Posted by tabstop View Post
    We take that for granted.

    But yes, the number is stored internally in binary, and 1/10 can not be represented exactly in binary. But hex is not involved in any way.
    Well I am not to sure what is happening really, probably not what I suspected, the only
    person who knows is the one who wrote the compiler.

    Of course if you make all the variables global it works <cough>

  13. #13
    Technical Lead QuantumPete's Avatar
    Join Date
    Aug 2007
    Location
    London, UK
    Posts
    894
    Quote Originally Posted by esbo View Post
    Well I am not to sure what is happening really, probably not what I suspected, the only
    person who knows is the one who wrote the compiler.
    Actually, it would be the committee that came up with the IEEE floating point standard. Floating point numbers are approximations, because decimal values cannot be accurately represented using binary. Thus 0.3 is actually .299999999999. If you then multiply that by 10 say (2.9999999999) and cast to an int, you get 2 (because int cast truncates), not 3, as you'd expect. This is a common occurrence in programs that mix floats and ints, which is why it's generally a good idea to avoid using floats or doubles whenever possible.
    There was an in-depth discussion of this a couple of months back, if you want to scour the archive.

    QuantumPete
    "No-one else has reported this problem, you're either crazy or a liar" - Dogbert Technical Support
    "Have you tried turning it off and on again?" - The IT Crowd

  14. #14
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    Quote Originally Posted by QuantumPete View Post
    Actually, it would be the committee that came up with the IEEE floating point standard. Floating point numbers are approximations, because decimal values cannot be accurately represented using binary. Thus 0.3 is actually .299999999999. If you then multiply that by 10 say (2.9999999999) and cast to an int, you get 2 (because int cast truncates), not 3, as you'd expect. This is a common occurrence in programs that mix floats and ints, which is why it's generally a good idea to avoid using floats or doubles whenever possible.
    There was an in-depth discussion of this a couple of months back, if you want to scour the archive.

    QuantumPete
    Well they might have wrote the standard, but I will bet you a pound to a penny they didn't
    write the compiler!!
    Anyway your explaintion does not explain the results for the program, does it?
    If so explain it in detail and how the error occurs whence it does.

  15. #15
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by esbo View Post
    Well they might have wrote the standard, but I will bet you a pound to a penny they didn't
    write the compiler!!
    Anyway your explaintion does not explain the results for the program, does it?
    If so explain it in detail and how the error occurs whence it does.
    I imagine the "error" is because the compiler is in strict compliance to the standard. How many more times do you want it explained?
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed