Thread: Floating Point Not Rounding

  1. #1
    Registered User
    Join Date
    Mar 2015
    Posts
    20

    Floating Point Not Rounding

    Basic question: Trying to learn C. The below code compiles properly and everything works except the input is not rounding properly. Note this is for a coarse and this is homework. Can someone explain why this isn't rounding?

    Code:
    /*
    This program prints a FLOATING POINT number input by the user and
    outputs it in a two decimal place format. It uses the function
    scanf for input and printf for output.
    */
    
    // INCLUDE SECTION
    #include <stdio.h>    // definitions for printf scanf getchar
    #include <conio.h>    // definitions for getch
    
    int main(int argc, char* argv[])
    {
        //    Variable Declaration
        float num;
    
        //    Get Input Number From User
        printf("\n\nPlease input a floating point number here ==> ");
        scanf_s("%f", &num);
    
        //    Print The Number To 2 Decimal Places
        printf("\nThe number is %.2f \n", num);
    
        //    Wait For The User To Press Any Key
        printf("Hit any key to continue...");
        _getch();
        return 0;
    }

  2. #2
    Registered User
    Join Date
    Oct 2010
    Posts
    132
    What is the value you're entering, and what the output should be, in your opinion?

  3. #3
    Registered User
    Join Date
    Mar 2015
    Posts
    20
    input = 9.995
    result = 9.99
    if i put in 9.996 it works

  4. #4
    Registered User
    Join Date
    Oct 2010
    Posts
    132
    Hum, you got me there. I don't know the reason for that output. Someone else might, though. Maybe some systems round the digit 5 down instead of up.
    Last edited by stdq; 04-21-2015 at 06:18 PM.

  5. #5
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    printf follows the more "statistically correct" way of rounding 5 to the nearest even number. As a result, if you want to round a 5, it depends whether the second digit left of it is even or odd( left of the one you round to ). If it is odd, you round down, if even you round up.
    Last edited by GReaper; 04-22-2015 at 01:02 AM.
    Devoted my life to programming...

  6. #6
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    printf follows the more "statistically correct" way of rounding 5 to the nearest even number. As a result, if you want to round a 5, it depends whether the second digit left of it is even or odd( left of the one you round to ). If it is odd, you round down, if even you round up.
    O_o

    The situation shown in the example doesn't have much to do with any tie-breaking aspects of the rounding method. The values `1.9375' and `1.890625' once rounded, with respect to the relevant `5' digit value, would show (`1.938' and `1.89062') the tie-breaking aspect of the rounding method. The values in the situation shown doesn't have an exact representation so no tie-breaking is necessary.

    The problem, of sorts, is how floating-point values are stored in binary.

    The value `9.995' is most likely `~9.9949998' which is just being rounded down.

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  7. #7
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    I was really interested in the explanations and made some tests...
    Code:
    #include<stdio.h>
    
    int main()
    {
        float f;
        double d;
        scanf("%f",&f);
        d = f;
        printf("%f %e %.2f\n",f,f,f );
        printf("%f %e %.2f\n",d,d,d );
        scanf("%f",&f);
        d = f;
        printf("%f %e %.2f\n",f,f,f );
        printf("%f %e %.2f\n",d,d,d );
        return 0;
    }
    And got following results
    9.995
    9.995000 9.995000e+00 9.99
    9.995000 9.995000e+00 9.99
    9.985
    9.985000 9.985000e+00 9.98
    9.985000 9.985000e+00 9.98
    look to me 5 is being rounded down no matter what...
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  8. #8
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    I was really interested in the explanations and made some tests...
    O_o

    Your test is flawed. Your results are irrelevant.

    The values `9.995' and `9.985' do not exist in IEEE754 binary, arguably the most common, representation.

    Code:
    #include <stdio.h>
    
    void Dump
    (
        float f
    )
    {
        char s[16];
        int c = 2;
        do {
            sprintf(s, "%%.%df\n", c);
            printf(s, f);
        } while(c++ < 9);
    }
    
    int main()
    {
        float s;
        while(1 == scanf("%f", &s))
        {
            Dump(s);
        }
        return(0);
    }
    Code:
    10.015
    10.005
    9.995
    9.985
    9.975
    Code:
    10.02
    10.015
    10.0150
    10.01500
    10.015000
    10.0150003
    10.01500034
    10.015000343
    10.01
    10.005
    10.0050
    10.00500
    10.005000
    10.0050001
    10.00500011
    10.005000114
    9.99
    9.995
    9.9950
    9.99500
    9.995000
    9.9949999
    9.99499989
    9.994999886
    9.98
    9.985
    9.9850
    9.98500
    9.985000
    9.9849997
    9.98499966
    9.984999657
    9.98
    9.975
    9.9750
    9.97500
    9.975000
    9.9750004
    9.97500038
    9.975000381
    look to me 5 is being rounded down no matter what...
    o_O

    You do not have a five.

    You have a five and a bit, or you have a four and a lot.

    If you want to see tie-breaking applied, you must use values which can be exactly represented.

    Code:
    #include <stdio.h>
    
    int main()
    {
        printf("%.4f\n", 1.40625f); // down
        printf("%.5f\n", 1.421875f); // up
        printf("%.5f\n", 1.453125f); // down
        printf("%.6f\n", 1.4609375f); // up
        return(0);
    }
    Strangely enough, the example I've provided may also fail to show tie-breaking behavior because not all compilers have enough precision to accurately encode values of the relevant precision.

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  9. #9
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o

    I am used to C++ so wasn't thinking about the `float'->`double' passing or the type of comments.

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem with rounding floating points
    By MacNilly in forum C++ Programming
    Replies: 3
    Last Post: 02-17-2006, 01:01 PM
  2. Floating point
    By Flip in forum C++ Programming
    Replies: 7
    Last Post: 12-05-2005, 12:29 PM
  3. Rounding a floating point #
    By john_murphy69 in forum C Programming
    Replies: 4
    Last Post: 01-22-2003, 09:47 PM
  4. fixed point / floating point
    By confuted in forum Game Programming
    Replies: 4
    Last Post: 08-13-2002, 01:25 PM
  5. Floating point faster than fixed-point
    By VirtualAce in forum A Brief History of Cprogramming.com
    Replies: 5
    Last Post: 11-08-2001, 11:34 PM