Thread: Float to int not truncating correctly

  1. #1
    Registered User
    Join Date
    Oct 2012
    Posts
    3

    Float to int not truncating correctly

    Hello,

    Code:
    #include <stdio.h>
    
    main()
    {
        int xs[] = {2,4,5,80,80,80,160,320,640,640};
        int i;
        double sum = 0;
        
        for(i = 0; i < 10; i++) {
            sum += (1.0/xs[i]);
        }
        
        i = sum;
        
        printf("sum = %f i = %d\n", sum, i); // i should be 1 ...
        
        if(i == 1) printf("Everyone is happy 1.\n");
        
        sum = 1.000000;
        i = sum;
        
        printf("sum = %f i = %d\n", sum, i); // now i = 1. why?
        
        if(i == 1) printf("Everyone is happy 2.\n");
    }
    A workaround is: i = sum+0.00001;
    But I was curious why it is happening. Anyone could explain, please?

    Thanks in advance.

    gcc version 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3)

  2. #2
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    You are asking too much from the floating point representation. The only fractional values that can be represented with complete accuracy are those that are (negative) powers of two or the sum of such powers. Anything else must be approximated.
    E.g.,
    0.5 decimal in binary is 0.1
    0.2 decimal in binary is 0.001100110011...

    So 0.5 can be represented with complete accuracy, but 0.2 cannot (similar to how 1/3 cannot be represented with complete accuracy in decimal).

    Thus the truncation is working perfectly since the approximated value is less than 1. Your workaround is the proper way to go, although you could probably just add DBL_EPSILON (from float.h).

    For all the info you'd ever want, see What Every Computer Scientist Should Know About Floating-Point Arithmetic
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  3. #3
    Registered User
    Join Date
    Sep 2008
    Posts
    200
    Quote Originally Posted by hi_friends View Post
    Code:
        sum = 1.000000;
        i = sum;
        
        printf("sum = %f i = %d\n", sum, i); // now i = 1. why?
    Is this code out of place or something? Of course i will be 1 - you've just set it to 1...

    Also, if you're having trouble rounding floating-point numbers, consider using round() from math.h.
    Programming and other random guff: cat /dev/thoughts > blogspot.com (previously prognix.blogspot.com)

    ~~~

    "The largest-scale pattern in the history of Unix is this: when and where Unix has adhered most closely to open-source practices, it has prospered. Attempts to proprietarize it have invariably resulted in stagnation and decline."

    Eric Raymond, The Art of Unix Programming

  4. #4
    Registered User
    Join Date
    Oct 2012
    Posts
    3
    Quote Originally Posted by JohnGraham View Post
    Is this code out of place or something? Of course i will be 1 - you've just set it to 1...
    Well, so I think you didn't run the code. I assign sum to i twice, and the first time sum also has the value 1.000000 (at least this is what is printed), but the value of i is ZERO.

    Quote Originally Posted by JohnGraham View Post
    Also, if you're having trouble rounding floating-point numbers, consider using round() from math.h.
    Thank you, but I don't want to round. I was just expecting a "proper" behavior for truncating.

  5. #5
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Quote Originally Posted by hi_friends View Post
    Well, so I think you didn't run the code. I assign sum to i twice, and the first time sum also has the value 1.000000 (at least this is what is printed), but the value of i is ZERO.
    Try using %.24f in the printf statement to see the actual value. You'll find that it's value is 0.999999999999999888977698 and not 1.

    (By the actual value, I mean that since IEEE-754 double-precision floating point has about 17 digits of precision, using 24 or so should give you a value which, when converted back to floating-point, has the exact same bit representation.)
    Last edited by Nominal Animal; 10-13-2012 at 07:52 PM.

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by hi_friends View Post
    Thank you, but I don't want to round. I was just expecting a "proper" behavior for truncating.
    The defined "proper" behaviour in C is rounding towards zero. So a floating point value which is very close to 1, but slightly less than 1, will become zero when converted to an int.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  7. #7
    Registered User
    Join Date
    Oct 2012
    Posts
    3
    Quote Originally Posted by Nominal Animal View Post
    Try using %.24f in the printf statement to see the actual value. You'll find that it's value is 0.999999999999999888977698 and not 1.

    (By the actual value, I mean that since IEEE-754 double-precision floating point has about 17 digits of precision, using 24 or so should give you a value which, when converted back to floating-point, has the exact same bit representation.)
    Very nice. Thank you.
    Sorry folks, the value of sum after the loop was not 1.
    Is there a way to mark the thread as solved?
    Thanks everyone.

  8. #8
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    I usually add 0.5 to a floating number before converting it to an int as a work around.
    Fact - Beethoven wrote his first symphony in C

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Float is truncating?!
    By JohnDeon in forum C Programming
    Replies: 10
    Last Post: 11-19-2011, 08:23 PM
  2. truncating front
    By jimmianlin in forum C Programming
    Replies: 2
    Last Post: 10-01-2009, 04:12 PM
  3. Rounding/truncating float to int
    By Zzaacchh in forum C++ Programming
    Replies: 4
    Last Post: 07-02-2008, 11:21 PM
  4. Truncating a char *
    By ajb268 in forum C++ Programming
    Replies: 3
    Last Post: 01-31-2005, 02:57 PM
  5. Truncating a double?
    By criticalerror in forum C++ Programming
    Replies: 13
    Last Post: 12-08-2003, 12:49 PM

Tags for this Thread