reorganization
This commit is contained in:
@@ -1,12 +1,11 @@
|
||||
#include "segment.hpp"
|
||||
|
||||
#include <bigmath/chain/segment_ops.hpp>
|
||||
|
||||
#include <bigmath/util/describe.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);
|
||||
|
||||
const u8 segment::digit_count = 128;
|
||||
const u8 segment::byte_count = segment::digit_count / 2;
|
||||
|
||||
@@ -85,65 +84,8 @@ namespace bigmath {
|
||||
segment low;
|
||||
segment high;
|
||||
|
||||
const u32 blen = segment::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);
|
||||
}
|
||||
|
||||
bigmath::mul_long(digits, s.digits, high.digits, low.digits, byte_count);
|
||||
|
||||
return { low, high };
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include <bigmath/BigMath.hpp>
|
||||
|
||||
#include <bigmath/util/util.hpp>
|
||||
|
||||
namespace bigmath {
|
||||
|
||||
/**
|
||||
|
||||
@@ -69,4 +69,69 @@ namespace bigmath {
|
||||
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