Skip to content

Instantly share code, notes, and snippets.

@apivovarov
Created February 21, 2025 22:24
Show Gist options
  • Save apivovarov/0d7b1072a852225d11bb45ff6a270a67 to your computer and use it in GitHub Desktop.
Save apivovarov/0d7b1072a852225d11bb45ff6a270a67 to your computer and use it in GitHub Desktop.
int32_t add_int32_using_float32(int32_t a, int32_t b) {
const uint32_t SHIFT = 16;
const uint32_t MASK = 0xFFFF;
int32_t a_high = a >> SHIFT; // Sign-extended
uint32_t a_low = static_cast<uint32_t>(a) & MASK;
int32_t b_high = b >> SHIFT; // Sign-extended
uint32_t b_low = static_cast<uint32_t>(b) & MASK;
// Add low parts (this will fit in float32)
float low_sum = static_cast<float>(a_low) + static_cast<float>(b_low);
// Handle carry from low parts
uint32_t carry = static_cast<uint32_t>(low_sum) >> SHIFT;
uint32_t low_result = static_cast<uint32_t>(low_sum) & MASK;
// Add high parts (this will fit in float32)
float high_sum = static_cast<float>(a_high) + static_cast<float>(b_high) +
static_cast<float>(carry);
uint32_t high_result = static_cast<uint32_t>(high_sum) & MASK;
// Combine results
uint32_t result = (high_result << SHIFT) | low_result;
return static_cast<int32_t>(result);
}
int main() {
std::vector<std::pair<int, int>> aa = {
{-1000000000, -1000000001},
{-1000000000, 1000000001},
{1000000000, -1000000001},
{1000000000, 1000000001},
{1500000000, 500000000},
{-500000000, 500000000},
{-2147483648, 1},
{-2147483648, -1},
{2147483647, 1},
{2147483647, -1},
{2000000000, 147483647},
{2000000000, 147483648},
{-2000000000, -147483648},
{-2000000000, -147483649},
{2000000000, -147483648},
};
for (auto a : aa) {
int32_t c = add_int32_using_float32(a.first, a.second);
int32_t ec = a.first + a.second;
std::cout << a.first << " + " << a.second << " = " << c << std::endl;
if (c != ec) {
std::cout << "Error: res / exp: " << c << " / " << ec << std::endl;
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment