reorganization

This commit is contained in:
2026-08-22 09:42:23 -06:00
parent 7692c04057
commit fe57c4390f
6 changed files with 90 additions and 62 deletions
View File
+3 -61
View File
@@ -1,12 +1,11 @@
#include "segment.hpp" #include "segment.hpp"
#include <bigmath/chain/segment_ops.hpp>
#include <bigmath/util/describe.hpp> #include <bigmath/util/describe.hpp>
namespace bigmath { namespace bigmath {
u8 add(u8* a, const u8* b, u8* c, u8 carry, u8 length);
u8 sub(u8* a, const u8* b, u8* c, u8 borrow, u8 length);
const u8 segment::digit_count = 128; const u8 segment::digit_count = 128;
const u8 segment::byte_count = segment::digit_count / 2; const u8 segment::byte_count = segment::digit_count / 2;
@@ -85,64 +84,7 @@ namespace bigmath {
segment low; segment low;
segment high; segment high;
const u32 blen = segment::byte_count; bigmath::mul_long(digits, s.digits, high.digits, low.digits, byte_count);
const u32 blen2 = blen * 2;
const u32 blen4 = blen * 4;
// Step 1: Unpack raw BCD bytes into raw digit buffers (0-9)
u8 digits_a[blen2];
u8 digits_b[blen2];
const u8* bytes_a = bytes();
const u8* bytes_b = s.bytes();
for (u32 i = 0; i < blen; ++i) {
u8 byte_a = bytes_a[i];
u8 byte_b = bytes_b[i];
digits_a[i * 2] = byte_a & 0x0F;
digits_a[i * 2 + 1] = byte_a >> 4;
digits_b[i * 2] = byte_b & 0x0F;
digits_b[i * 2 + 1] = byte_b >> 4;
}
// Step 2: Accumulate digit products into temporary array of size blen4
u16 accum[blen4] = {};
for (u32 i = 0; i < blen2; ++i) {
u8 d1 = digits_a[i];
if (d1 == 0) continue; // Skip zeros
for (u32 j = 0; j < blen2; ++j) {
u8 d2 = digits_b[j];
accum[i + j] += static_cast<u16>(static_cast<u16>(d1) * static_cast<u16>(d2));
}
}
// Step 3: Base-10 Carry Propagation and Direct Packed BCD Storage
u32 carry = 0;
u8 out_digits[blen4];
for (u32 i = 0; i < blen4; ++i) {
u32 sum = accum[i] + carry;
out_digits[i] = static_cast<u8>(sum % 10);
carry = sum / 10;
}
// Step 4: Pack result digits directly into low and high segment bytes
for (u32 i = 0; i < blen; ++i) {
u8 low_digit0 = out_digits[i * 2];
u8 low_digit1 = out_digits[i * 2 + 1];
u8 high_digit0 = out_digits[i * 2 + blen2];
u8 high_digit1 = out_digits[i * 2 + blen2 + 1];
low.set(static_cast<u8>(i * 2), low_digit0);
low.set(static_cast<u8>(i * 2 + 1), low_digit1);
high.set(static_cast<u8>(i * 2), high_digit0);
high.set(static_cast<u8>(i * 2 + 1), high_digit1);
}
return { low, high }; return { low, high };
} }
+2
View File
@@ -2,6 +2,8 @@
#include <bigmath/BigMath.hpp> #include <bigmath/BigMath.hpp>
#include <bigmath/util/util.hpp>
namespace bigmath { namespace bigmath {
/** /**
+65
View File
@@ -69,4 +69,69 @@ namespace bigmath {
return borrow; return borrow;
} }
void mul_long(const u8* a, const u8* b, u8* c_high, u8* c_low, u8 length) {
const u32 blen = length;
const u32 blen2 = blen * 2;
const u32 blen4 = blen * 4;
// Step 1: Unpack raw BCD bytes into raw digit buffers (0-9)
u8 digits_a[blen2];
u8 digits_b[blen2];
for (u32 i = 0; i < blen; ++i) {
u8 byte_a = a[i];
u8 byte_b = b[i];
digits_a[i * 2] = byte_a & 0x0F;
digits_a[i * 2 + 1] = byte_a >> 4;
digits_b[i * 2] = byte_b & 0x0F;
digits_b[i * 2 + 1] = byte_b >> 4;
}
// Step 2: Accumulate digit products into temporary array of size blen4
u16 accum[blen4] = {};
for (u32 i = 0; i < blen2; ++i) {
u8 d1 = digits_a[i];
if (d1 == 0) continue; // Skip zeros
for (u32 j = 0; j < blen2; ++j) {
u8 d2 = digits_b[j];
accum[i + j] += static_cast<u16>(static_cast<u16>(d1) * static_cast<u16>(d2));
}
}
// Step 3: Base-10 Carry Propagation and Direct Packed BCD Storage
u32 carry = 0;
u8 out_digits[blen4];
for (u32 i = 0; i < blen4; ++i) {
u32 sum = accum[i] + carry;
out_digits[i] = static_cast<u8>(sum % 10);
carry = sum / 10;
}
// Step 4: Pack result digits directly into low and high segment bytes
for (u32 i = 0; i < blen; ++i) {
u8 low_digit0 = out_digits[i * 2];
u8 low_digit1 = out_digits[i * 2 + 1];
u8 high_digit0 = out_digits[i * 2 + blen2];
u8 high_digit1 = out_digits[i * 2 + blen2 + 1];
// No longer using the object version,
// so we set the bytes ourselves!
c_low[i] = low_digit0 | low_digit1 << 4;
//low.set(static_cast<u8>(i * 2), low_digit0);
//low.set(static_cast<u8>(i * 2 + 1), low_digit1);
c_high[i] = high_digit0 | high_digit1 << 4;
//high.set(static_cast<u8>(i * 2), high_digit0);
//high.set(static_cast<u8>(i * 2 + 1), high_digit1);
}
// end!
}
} }
+19
View File
@@ -0,0 +1,19 @@
#pragma once
#include <bigmath/BigMath.hpp>
namespace bigmath {
u8 add(u8* a, const u8* b, u8* c, u8 carry, u8 length);
u8 sub(u8* a, const u8* b, u8* c, u8 borrow, u8 length);
void mul_long(const u8* a, const u8* b, u8* c_high, u8* c_low, u8 length);
void mul_karatsuba(const u8* a, const u8* b, u8* c_high, u8* c_low, u8 length);
void div_long(const u8* a, const u8* b, u8* quot, u8* rem, u8 length);
void div_newtonraphson(const u8* a, const u8* b, u8* quot, u8 length);
}