Created
November 23, 2023 03:29
-
-
Save reedacartwright/5406a00225c7508f5e9d3c47604d460d to your computer and use it in GitHub Desktop.
Full width multiplication of two 32-bit numbers.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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