#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2012
    Posts
    3
    Rep Power
    0

    Help needed in c


    Hello guys im new to this forum at c programming as well. anyways here is the code, can somebody explain why the output includes the number 2 as well

    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include<string.h>

    int main(int argc, char *argv[])
    {

    int i;
    float r=0.0;
    while(r<1.8)
    {
    r+=0.3;
    i=r;
    printf("%d\n",i);
    }
    system("PAUSE");
    return 0;
    }
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2012
    Posts
    62
    Rep Power
    4
    It could be rounding the number to the nearest whole number when it's parsed (if that's the right word) to the type int.

    What are you trying to achieve anyway?

    Regards,

    Shaun.
    Edit: This code will stop it from outputting the number 2 -
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <conio.h>
    //#include <string.h>
    
    int main(int argc, char *argv[])
    {
        int i;
        float r=0.00f;
        while(r<1.7) // 1.8 + 0.3 = ???
        {
            r+=0.3;
            i=r;
            printf("%d\n",i);
        }
        _getch();
        return 0;
    }
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2012
    Posts
    3
    Rep Power
    0
    Originally Posted by Shaun_B
    It could be rounding the number to the nearest whole number when it's parsed (if that's the right word) to the type int.

    What are you trying to achieve anyway?

    Regards,

    Shaun.
    i was just doing an online quiz that asked for the output, i didnt include the number 2
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2012
    Posts
    62
    Rep Power
    4
    Originally Posted by imra
    i was just doing an online quiz that asked for the output, i didnt include the number 2
    I see, check out my code above in the edited post.

    Regards,

    Shaun.
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2012
    Posts
    3
    Rep Power
    0
    Originally Posted by Shaun_B
    I see, check out my code above in the edited post.

    Regards,

    Shaun.
    thx, but i still can understand why the value 2 is in the output, shouldnt it exit the loop when it reaches 1.8
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2012
    Posts
    62
    Rep Power
    4
    Originally Posted by imra
    thx, but i still can understand why the value 2 is in the output, shouldnt it exit the loop when it reaches 1.8
    Okay, so if you copy a floating point number to an integer, you'll get that number rounded down, so your condition is counting to 1.8, and while it's less that 1.8, it's adding 0.3.

    So, when it gets to 1.7, it adds 0.3. Then i is made equal to the int value of 1.7 + 0.3.

    Simple.
  12. #7
  13. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,966
    Rep Power
    481
    I really don't understand how you'd get a value near 1.7 in there.

    0.3 cannot be represented exactly in (a finite number of digits) base 2. Binary. Just as 1/3 cannot be represented exactly in a finite number of base 10 digits.

    So 0.3 represented in base 2 must be just a little bit less than 0.3. When you add 6 of them you get a number that's slightly less than 1.8, your code doesn't terminate when you expect, it adds to almost 2.1 . (int)2.1 is 2.

    Some base 2 fractions written in j.
    Code:
       input
    output
       input sentence
    result
       input
    output
    Code:
       2b0.01001100110011   NB. base 2 fraction
    0.299988
       2b0.010011001100110011   NB. 0.3 in base 2 is 0.10011...  repeating  0011 forever
    0.299999
              2b0.0100110011001100110011    NB.  pretty close to 0.3 base 10
    0.3
       19j16":2b0.0100110011001100110011    NB. display with more digits
     0.2999999523162842
    [code]Code tags[/code] are essential for python code and Makefiles!
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2012
    Posts
    5
    Rep Power
    0
    Originally Posted by b49P23TIvg
    I really don't understand how you'd get a value near 1.7 in there.

    0.3 cannot be represented exactly in (a finite number of digits) base 2. Binary. Just as 1/3 cannot be represented exactly in a finite number of base 10 digits.

    So 0.3 represented in base 2 must be just a little bit less than 0.3. When you add 6 of them you get a number that's slightly less than 1.8, your code doesn't terminate when you expect, it adds to almost 2.1 . (int)2.1 is 2.

    Some base 2 fractions written in j.
    Code:
       input
    output
       input sentence
    result
       input
    output
    Code:
       2b0.01001100110011   NB. base 2 fraction
    0.299988
       2b0.010011001100110011   NB. 0.3 in base 2 is 0.10011...  repeating  0011 forever
    0.299999
              2b0.0100110011001100110011    NB.  pretty close to 0.3 base 10
    0.3
       19j16":2b0.0100110011001100110011    NB. display with more digits
     0.2999999523162842

    Thats right.
    if you want to understand clearly see the below steps
    i got it through GDB.

    when you add 0.3 to 1.5 in binary it is not equal to 1.8 rather it is 1.79999 so is less than 1.8.

    Breakpoint 1, main () at test.c:5
    5 float r= 0.0;
    (gdb) s
    7 while(r < 1.8) {
    (gdb) s
    8 r += 0.3;
    (gdb) p r
    $1 = 0
    (gdb) s
    9 i = r;
    (gdb) p r
    $2 = 0.300000012
    (gdb) s
    10 printf(" %d\n" , i);
    (gdb) s
    0
    7 while(r < 1.8) {
    (gdb) s
    8 r += 0.3;
    (gdb) s
    9 i = r;
    (gdb) p r
    $3 = 0.600000024
    (gdb) s
    10 printf(" %d\n" , i);
    (gdb) s
    0
    7 while(r < 1.8) {
    (gdb) s
    8 r += 0.3;
    (gdb) s
    9 i = r;
    (gdb) p r
    $4 = 0.900000036
    (gdb) s
    10 printf(" %d\n" , i);
    (gdb) s
    0
    7 while(r < 1.8) {
    (gdb) s
    8 r += 0.3;
    (gdb) s
    9 i = r;
    (gdb) p r
    $5 = 1.20000005
    (gdb) s
    10 printf(" %d\n" , i);
    (gdb) s
    1
    7 while(r < 1.8) {
    (gdb) s
    8 r += 0.3;
    (gdb) s
    9 i = r;
    (gdb) p r
    $6 = 1.5
    (gdb) s
    10 printf(" %d\n" , i);
    (gdb) s
    1
    7 while(r < 1.8) {
    (gdb) s
    8 r += 0.3;
    (gdb) s
    9 i = r;
    (gdb) p r
    $7 = 1.79999995
    (gdb) s
    10 printf(" %d\n" , i);
    (gdb) s
    1
    7 while(r < 1.8) {
    (gdb) s
    8 r += 0.3;
    (gdb) s
    9 i = r;
    (gdb) p r
    $8 = 2.0999999
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2012
    Posts
    156
    Rep Power
    34
    Because 0.3 + 0.3 + 0.3 + 0.3 + 0.3 + 0.3 < 1.8.

    You need to read What Every Programmer Should Know About Floating-Point Arithmetic.
  18. #10
  19. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,966
    Rep Power
    481
    I always use integral looping to know what I'm getting.

    And when I don't, I use a floating point limit pinned to a half step.
    [code]Code tags[/code] are essential for python code and Makefiles!
  20. #11
  21. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2012
    Posts
    62
    Rep Power
    4
    How I got 1.7... because my maths aren't very good. This clarifies everything:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include<string.h>
    
    int main(int argc, char *argv[])
    {
        int i;
        float r=0.0;
        printf("Vaules of r and i before loop:\ni = %d r = %f",i,r);
        printf("\nAnd here's the values outputted during the loop:\n");
        while(r<1.8)
        {
            r+=0.3;
            i=r;
            printf(" i = %d r = %f\n", i, r);
        }
        //system("PAUSE");
        return 0;
    }
    Printing out variables that aren't initialised is fun.

IMN logo majestic logo threadwatch logo seochat tools logo