Skip to content

Instantly share code, notes, and snippets.

@reedacartwright
Created November 23, 2023 03:29
Show Gist options
  • Save reedacartwright/5406a00225c7508f5e9d3c47604d460d to your computer and use it in GitHub Desktop.
Save reedacartwright/5406a00225c7508f5e9d3c47604d460d to your computer and use it in GitHub Desktop.
Full width multiplication of two 32-bit numbers.
/*
This file contains examples of how to do full-width 32-bit multiplication by dividing each
operand into 16-bit fields.
*/
typedef struct {
int low;
int high;
} int_pair_t;
// Extract high and low parts of a 32-bit number without sign extension
#define high_part(x) ((x >> 16) & 0xFFFF)
#define low_part(x) ((x) & 0xFFFF)
// Multiply two 32-bit numbers and return the 64-bit result as two 32-bit numbers.
// It does multiplication assuming that the inputs are unsigned.
int_pair_t umult(int a, int b) {
int x0 = low_part(a) * low_part(b);
int x1 = low_part(a) * high_part(b);
int x2 = high_part(a) * low_part(b);
int x3 = high_part(a) * high_part(b);
// This will not carry
x1 += high_part(x0);
x1 += low_part(x2);
// Calculate the high and low parts of the result
int_pair_t result;
result.low = low_part(x0) + (low_part(x1) << 16);
result.high = x3 + high_part(x1) + high_part(x2);
return result;
}
// Does signed multiplication of two signed numbers by adjusting the result of
// unsigned multiplication.
int_pair_t smult(int a, int b) {
int_pair_t result = umult(a, b);
result.high -= ((a < 0) ? b : 0);
result.high -= ((b < 0) ? a : 0);
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment