Mike Copeland wrote:
> What are some accepted ways to do the following calculation - and
> avoid the compiler warnings that expose conversion data loss? (I'm
> trying to compute the total time in seconds that a person has to
> complete an event, based on a stated pace.) TIA
>
> double dDistance = 6.214;
> time_t tPace = 600;
> time_t tEstTime;
>
> tEstTime = tPace * dDistance;
As the type of dDistance is double and the typeof tPace is time_t, the
expression "tPace * dDistance" is evaluated to an object of type double.
Then, the result of that expression is assigned to tEstTime, which is
another object of type time_t.
The thing with time_t is that it is an unsigned integer type. If the
expression "tPace*dDistance" returns a negative value then maybe all sorts
of hell will breaks loose, as this behavior is left undefind in the
standard.
If, instead, the "tPace*dDistance" expression is evaluated to a positive
number then the assignment will truncate the resulting value towards zero.
There's not much that can be done about it, other than making sure that,
instead of truncating it, we make sure the value is rounded. There are some
simple[¹] and convoluted[2] suggestions floating around, but, at least since
C99, it's possible to avoid all that with a simple call to
nearbyint(tPace*dDistance).
Another detail which is rarely mentioned is the possibility of a floating
point operation having been raised, which includes the possibility of
dDistance ending up storing an invalid value, such as NaN or divide-by-zero.
Checking the floating point exception flags can save some headaches.
So, data will be lost either way. You just need to make sure that dDistance
stores a valid positive value and then assign it to tEstTime. If you can
ensure that then it's safe to assume that the only conversion loss that can
happen is the loss of the fractional part of your floating point value.
Having done that then you will probably get rid of those warnings about
conversion loss once you cast the result back to time_t. And that's about
it.
Hope this helps,
Rui Maciel
[¹]
http://c-faq.com/fp/round.html
[2]
http://www.cs.tut.fi/~jkorpela/round.html