79 lines
1.8 KiB
C++
79 lines
1.8 KiB
C++
#include "segment.hpp"
|
|
|
|
#include <sstream>
|
|
#include <iomanip>
|
|
|
|
namespace bigmath {
|
|
|
|
const dlen_t segment::digit_count = 128;
|
|
const dlen_t segment::byte_count = segment::digit_count / 2;
|
|
|
|
segment::segment() {
|
|
digits = new dlen_t[byte_count]{};
|
|
}
|
|
|
|
segment::~segment() {
|
|
delete[] digits;
|
|
}
|
|
|
|
d10_t segment::operator[](dlen_t i) const {
|
|
dlen_t j = i >> 1;
|
|
dlen_t k = (i & 1) * 4;
|
|
d10_t b = digits[j];
|
|
return (b >> k) & 0xFu;
|
|
}
|
|
|
|
void segment::set(dlen_t i, d10_t n) {
|
|
dlen_t j = i >> 1;
|
|
dlen_t k = (i & 1) * 4;
|
|
d10_t b = digits[j];
|
|
b &= 0xF0u >> k;
|
|
n &= 0xFu;
|
|
digits[j] = b | (n << k);
|
|
}
|
|
|
|
const digits_t segment::bytes() const {
|
|
return digits;
|
|
}
|
|
|
|
std::string segment::describe() const {
|
|
std::ostringstream out;
|
|
|
|
// We'll iterate backwards
|
|
size_t i = digit_count;
|
|
u32 use_space = 0;
|
|
while (i > 0) {
|
|
d10_t val = operator[](i - 1);
|
|
|
|
// Count repetitions
|
|
size_t count = 1;
|
|
while (i > count && operator[](i - count - 1) == val) ++count;
|
|
|
|
// temporal string
|
|
std::ostringstream one;
|
|
one << u32(val);
|
|
auto str = one.str();
|
|
|
|
// Decide whether to compress
|
|
if (count > 5) {
|
|
if(use_space) out << " ";
|
|
out << "[" << str << " x " << count << "]";
|
|
use_space = 4;
|
|
} else {
|
|
for (size_t j = 0; j < count; ++j) {
|
|
if(use_space > 3) {
|
|
out << " ";
|
|
use_space = 1;
|
|
}
|
|
use_space++;
|
|
out << str;
|
|
}
|
|
}
|
|
|
|
i -= count;
|
|
}
|
|
|
|
return out.str();
|
|
}
|
|
|
|
} |