Is there a way to store lower 64 bits of multiplication int64_t * int64_t in C?
Solution 1:
When an int64_t
is multiplied by an int64_t
, the true arithmetic result is a 128-bit number with its sign bit at bit 127. The low 64 bits do not contain a sign bit. Therefore, the low 64 bits of the multiplication ought to be returned in a uint64_t
, not an int64_t
, and this can be accomplished with:
imull(int64_t a, int64_t b, uint64_t *res)
{
*res = (uint64_t) a * (uint64_t) b;
}
(The casts avoid overflow in the multiplication, as unsigned integer arithmetic is defined to wrap, not overflow.)
If the bits must be returned in an int64_t
, this can be done in a way defined by the C standard using:
imull(int64_t a, int64_t b, int64_t *res)
{
uint64_t temporary = (uint64_t) a * (uint64_t) b;
memcpy(res, &temporary, sizeof *res);
}
(memcpy
is declared in <string.h>
.)
Also note that if the true arithmetic result fits in an int64_t
, then the int64_t
returned by the above code will equal the true arithmetic result. (This is a property of the two’s complement representation, which int64_t
uses.)