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