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

    Join Date
    Jun 2013
    Posts
    142
    Rep Power
    1

    Data type question


    I want to ask about the behavior of the following function.
    Code:
    double get_seconds (double time)
    {
        double seconds;
        seconds = (time - (int)time) * 60;
        return(seconds);
    }
    For input 2.4, this code correctly gives the output 24.00.
    However, if I change the variable seconds to an integer, the return value is 23.
    Why does this happen?
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    159
    Rep Power
    19
    Have you tried to either print this return value using a precision of say 15 and see what the actual value is, or run the program with your debugger and viewing the variables as you single step thru the program.

    Jim
  4. #3
  5. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,091
    Rep Power
    2222
    In case you are brushing off jimblumberg's suggestion, consider this common problem.

    In school 34 years ago, we learned a numerical method for linear programming that employed what's called a pivot table. We were to perform a matrix operation on that table that would cause a particular row/column intersection to contain a 0.0. So I set everything up and tested for 0.0 in that cell and the program failed every time. When I worked it out by hand, it worked every time, but the program which did the "exact same thing" failed every time. I couldn't see what I was doing wrong.

    The problem was two-fold. First, every time you perform a floating-point operation, you can incur some round-off error. Second, while we think in terms of decimal fractions, computers think in binary fractions -- base 2, not base 10. A decimal fraction operation that would work out evenly without any error (eg, multiplying or dividing by powers of ten), would not work out evenly in base 2.

    So back to my problem with that pivot table. After a series of floating-point operations, I was expecting the result to be 0.0 exactly. It wasn't. It could not be expected to be. Very close to 0.0, but not 0.0 exactly.

    In decimal, your calculation of seconds would come out with 24 seconds exactly. In binary reality, the evaluation of that expression comes out with 24 seconds approximately. "Approximately" means that it could be just the tiniest bit greater than 24, or just the tiniest bit less. Truncation knows nothing about "close enough". If it's equal to or greater than 24.0, then it will be 24. Even the tiniest bit less and it's 23. Display that double value out to the very last bit and you will see what it really is.

    Consider rounding off instead of truncating. Add 0.5 to the result and then truncate it to int. See what you get.
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    142
    Rep Power
    1
    Thanks for the replies.

    Have you tried to either print this return value using a precision of say 15
    I did that, and I got 23.99...93.

    I now see why I got 23 for the return value; since the value of seconds is actually 23.99....3... , which is less than 24, making seconds an int variable and truncating the fractional part gave 23.

    Consider rounding off instead of truncating. Add 0.5 to the result and then truncate it to int. See what you get.
    Tried and worked.
    As always, thank you for the detailed explanation.

IMN logo majestic logo threadwatch logo seochat tools logo