Why Tea wrote:
I understood that the CPU registers determine the size of the
machine.
[OT: If you say so. Some people use the size of the address
bus, e.g. the original Macs used an m68k and was considered
a 16-bit machine even though registers are 32-bits.]
But what is the correct way to code an arithmetic
operation to avoid wrap-around
Do you mean unsigned modulo arithmetic?
when the code is to be run on both 32-
bit and 64-bit machines?
If you need a 64-bit result, then it doesn't matter whether
you're using a 32 or 64-bit machine, you use a 64-bit type,
if available.
Example:
uint32_t x = SOME_LARGE_NO;
uint64_t y;
Why are you using precise width types?
...
y = (uint64_t)(10000 * x); */* Will overflow occur before
the cast? */
Possibly.
y = (int64_t)(x) * 10000; * /* or, is it better to do the
cast first? */
Did you really mean to cast with (uint64_t)? Your cast will
work, but it's not obvious why you're switching between
signednesss.
The 'factor' of 10000 is enough to avoid overflow in either
case, but a more robust solution would be to preserve the
signness in cases where the factor might be (say) 0xF0000000.
jacob navia <ja...@nospam.comwrote:
Do operations in 64 *bit arithmetic
The second is better. Or even better
*y = (int64_t)(x) * 10000LL; */* put constant in 64 bits
using LL suffix */
How is this better? The presence of the cast on x means the
constant will be converted (if necessary) to a type that is
at least 64-bits anyway.
If the result is truly meant to be a 64-bit unsigned value
from a multiplication of two non-negative 32-bit values,
one of which is explicitly unsigned, then the following is
adequate...
y = x * 10000ull;
Even if unsigned long long is 128-bits (say), an optimiser
should be able to recognise that only 64-bits is significant
and a 64-bit calculation is all that is needed.
Alternatively...
y = x;
y *= 10000;
--
Peter