June 16th, 2013, 07:56 PM
Data type question
I want to ask about the behavior of the following function.
For input 2.4, this code correctly gives the output 24.00.
double get_seconds (double time)
seconds = (time - (int)time) * 60;
However, if I change the variable seconds to an integer, the return value is 23.
Why does this happen?
June 16th, 2013, 08:16 PM
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.
June 17th, 2013, 01:43 AM
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.
June 17th, 2013, 02:13 AM
Thanks for the replies.
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.
Tried and worked.
As always, thank you for the detailed explanation.