reorganization
This commit is contained in:
@@ -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,6 +2,8 @@
|
|||||||
|
|
||||||
#include <bigmath/BigMath.hpp>
|
#include <bigmath/BigMath.hpp>
|
||||||
|
|
||||||
|
#include <bigmath/util/util.hpp>
|
||||||
|
|
||||||
namespace bigmath {
|
namespace bigmath {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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!
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user