0.01, the mathematical result of 10 / 1000, is not representable exactly in binary. It is possible that one compiler uses greater precision than required by the type (here, float
) for intermediate floating-point results. This is allowed, in a precisely defined manner, in C99, as long as the compiler defines FLT_EVAL_METHOD
to 1 or 2. Some non-c99 compilers also let intermediate results have excess precision, this time without a clear definition of when rounding can or cannot happen.
In binary, it is possible that the closest representation of 0.01 is higher than 0.01 at one precision, and lower at another. This would explain the 19 with your compiler and the 20 with ideone.
A compiler that would respect C99's rules for where excess precision is allowed would have no excuse to produce different values for ticksInt
and ticksUint
. However, a compiler that does not respect these rules can generate code that causes this to happen.
Adding -std=c99
to the commandline options makes GCC respect the letter of the C99 standard with respect to excess precision for floating-point expressions. Without this option, GCC's behavior with respect to excess precision (when excess precision there has to be, that is, when generating code for the 387 FPU) is very “casual”: results are kept in 80-bit registers and spilled to 64- or 32-bit slots on the stack at the compiler's whim, with no intervention of the programmer, causing unpredictable, erratic results.
This could completely explain what you are observing when you compile at home: for some unfathomable reason the value is converted to int
directly from the 80-bit register but has gone from a 80-bit register to a 32-bit slot when the conversion to unsigned int
takes place.
If this is the correct explanation, your solutions are:
do not generate 387 code: use GCC options
-msse2 -mfpmath=sse
;use
-std=c99
that, with a recent GCC, cause a sensible interpretation of what “excess precision” means, making floating-point code predictable;do all computations in the
long double
type.
Please see the “This Said” part of this answer for additional details.