77 BCD_error orig_error : 4;
99 .
data = (packed_BCD_pair[]) {2},
108 .
data = (packed_BCD_pair[]) {1},
208 BCD_int BCD_from_bytes(
const unsigned char *
const str,
const size_t chars,
const bool negative,
const bool little_endian);
1020 uint16_t
mul_dig_pair(
const packed_BCD_pair ab,
const packed_BCD_pair cd);
1058 .negative = negative,
1061 .decimal_digits = (
size_t) ceil(log10((
double) (a + 1))),
1064 c.
data = (packed_BCD_pair *) malloc(
sizeof(packed_BCD_pair) * c.
bcd_digits);
1068 c.
data[i] = (((a % 100) / 10) << 4) | (a % 10);
1076 const packed_BCD_pair *
const data = a.
data;
1077 a.
data = (packed_BCD_pair *) malloc(
sizeof(packed_BCD_pair) * a.
bcd_digits);
1086 BCD_int BCD_from_bytes(
const unsigned char *
const str,
const size_t chars,
const bool negative,
const bool little_endian) {
1088 if (!chars || str == NULL)
1092 .negative = negative,
1093 .data = (packed_BCD_pair *) malloc(
sizeof(packed_BCD_pair) * chars),
1097 if (little_endian) {
1098 memcpy(c.
data, str, chars);
1102 for (i = 0, j = chars - 1; i < chars; i++, j--) {
1106 for (i = chars - 1; i != -1; i--) {
1109 if (c.
data[i] & 0xF0)
1126 const size_t length = (digits + 1) / 2;
1128 unsigned char *
const bytes = (
unsigned char *) malloc(
sizeof(
unsigned char) * length);
1131 if ((j = i = digits % 2))
1132 bytes[0] = str[0] -
'0';
1133 for (; i < length; i++, j += 2) {
1134 bytes[i] = ((str[j] -
'0') << 4) | ((str[j + 1] -
'0') & 0xF);
1144 .orig_error = orig_error
1163 for (
size_t i = x.
bcd_digits - 1; i != -1; i--) {
1188 return sign_bcd(x, no_copy,
false);
1215 .data = (packed_BCD_pair *) malloc(
sizeof(packed_BCD_pair) * (x.
bcd_digits + 1)),
1220 uint8_t overflow =
false;
1221 packed_BCD_pair a, b,
c;
1225 if (!(overflow || a)) {
1229 else if (!(overflow || b)) {
1235 #if (!defined(NO_ASSEMBLY) && X86_COMPILER) // if on these architectures, there's assembly tricks to adjust BCD in-silicon 1263 #else // otherwise fall back to doing it in C 1265 if ((overflow = (a > 0x99 - b)))
1267 if (((a & 0xF) + (b & 0xF)) > 9)
1274 a = x.
data[i] + overflow;
1275 if ((a & 0x0F) == 0x0A)
1277 if ((overflow = ((a & 0xF0) == 0xA0)))
1305 const comp_t cmp =
cmp_bcd(x, y);
1316 .
data = (packed_BCD_pair *) malloc(
sizeof(packed_BCD_pair) * x.
bcd_digits),
1323 packed_BCD_pair a, b,
c;
1328 #if (!defined(NO_ASSEMBLY) && X86_COMPILER) // if on these architectures, there's assembly tricks to adjust BCD in-silicon 1356 #else // otherwise fall back to doing it in C. the code below should replicate the DAS x86 instruction 1357 const uint8_t old_c = c = a - b;
1358 const bool AF = ((int8_t) (a & 0x0F) - (b & 0x0F)) < 0;
1359 const bool old_carry = ((int16_t) a - b) < 0;
1361 if (AF || ((c & 0x0F) > 0x09)) {
1362 carry = old_carry || (((int16_t) c - 0x06) < 0);
1365 if (old_carry || (old_c > 0x99)) {
1373 a = x.
data[i] - carry;
1374 if ((a & 0x0F) == 0x0F)
1376 if ((carry = ((a & 0xF0) == 0xF0)))
1386 if (z.
data[i] & 0xF0)
1423 size_t i, j, pow_10, ipow_10 = 0;
1426 for (i = 0; i < x.
bcd_digits; i++, ipow_10 += 2) {
1427 for (j = 0, pow_10 = ipow_10; j < y.
bcd_digits; j++, pow_10 += 2) {
1440 const size_t cutoff = digits / 2;
1450 z1 =
add_bcd(x_lower, x_higher),
1451 z2 =
mul_bcd(x_higher, y_higher);
1452 tmp =
add_bcd(y_lower, y_higher);
1488 BCD_error error, orig_error;
1491 orig_error = x.orig_error;
1493 orig_error = y.orig_error;
1525 if ((div.
negative = (x_negative != y_negative))) {
1531 else if (mod != NULL)
1535 else if (mod != NULL) {
1536 *mod =
sign_bcd(tmp,
true, y_negative);
1546 BCD_error error, orig_error;
1552 orig_error = (x.
nan) ? x.orig_error : y.orig_error;
1567 while (!tmp_y.zero) {
1679 uintmax_t answer = 0, pow_10 = 1;
1680 for (
size_t i = 0; i < x.
bcd_digits; i++, pow_10 *= 100) {
1681 answer += pow_10 * ((x.
data[i] & 0x0F) + 10 * (x.
data[i] >> 4));
1683 if ((x.
data[0] & 0xF) != (answer % 10))
1692 if (answer > (uintmax_t) INTMAX_MAX)
1694 return ((x.
negative) ? -((intmax_t) answer) : (intmax_t) answer);
1704 return inverse_answer;
1748 while (y % 10 == 0) {
1785 ret.
data = (packed_BCD_pair *) calloc(ret.
bcd_digits,
sizeof(packed_BCD_pair));
1788 if (tens % 2 == 0) {
1804 ret.
data[digit_diff] = x.
data[0] << 4;
1806 ret.
data[i + digit_diff] = x.
data[i] << 4;
1807 ret.
data[i + digit_diff] |= x.
data[i - 1] >> 4;
1831 ret.
data = (packed_BCD_pair *) malloc(
sizeof(packed_BCD_pair) * ret.
bcd_digits);
1834 if (tens % 2 == 0) {
1849 ret.
data[0] = a.
data[digit_diff] >> 4;
1850 for (
size_t i = 1; i < ret.
bcd_digits; i++) {
1851 ret.
data[i - 1] |= a.
data[i + digit_diff] << 4;
1852 ret.
data[i] = a.
data[i + digit_diff] >> 4;
1915 inline uint16_t
mul_dig_pair(
const packed_BCD_pair ab,
const packed_BCD_pair cd) {
1918 const uint8_t a = ab >> 4,
1923 return 100 * a * c + 10 * (a * d + b * c) + b * d;
1938 printf(
"%x", x.
data[i--]);
1939 for (; i != -1; i--) {
1940 printf(
"%02x", x.
data[i]);
BCD_int mul_bcd(const BCD_int x, const BCD_int y)
Definition: bcd.h:1403
void ipow_bcd(BCD_int *const x, const BCD_int y)
Definition: bcd.h:1664
void imod_bcd(BCD_int *const x, const BCD_int y)
Definition: bcd.h:1650
void imul_bcd_cuint(BCD_int *const x, const uintmax_t y)
Definition: bcd.h:1883
uint16_t mul_dig_pair(const packed_BCD_pair ab, const packed_BCD_pair cd)
Multiply a pair of BCD bytes.
Definition: bcd.h:1915
you tried to divide NaN
Definition: bcd.h:54
you tried to do a yet-unimplemented feature
Definition: bcd.h:62
bool zero
indicates the integer is 0
Definition: bcd.h:81
void idiv_bcd(BCD_int *const x, const BCD_int y)
Definition: bcd.h:1644
const BCD_int BCD_two
The BCD_two constant is used to represent the commonly used value two.
Definition: bcd.h:98
void imul_bcd_cint(BCD_int *const x, const intmax_t y)
Definition: bcd.h:1889
void iabs_bcd(BCD_int *const x)
Definition: bcd.h:1602
size_t decimal_digits
the number of decimal digits in this integer
Definition: bcd.h:72
comp_t cmp_bcd(const BCD_int x, const BCD_int y)
Definition: bcd.h:1148
void idivmod_bcd(BCD_int *const x, BCD_int *const y)
Definition: bcd.h:1656
BCD_int shift_bcd_right(const BCD_int a, const size_t tens)
Definition: bcd.h:1861
BCD_int sign_bcd(BCD_int x, const bool no_copy, const bool negative)
Definition: bcd.h:1181
bool constant
indicates that the integer is a constant and will not be touched by free_bcd_int() ...
Definition: bcd.h:83
void free_BCD_int(BCD_int *const x)
Definition: bcd.h:1043
#define likely(x)
Indicates to the compiler (if supported) that this branch is likely to occur and it should arrange co...
Definition: math.h:143
const BCD_int BCD_one
The BCD_one constant is used to represent the commonly used value one.
Definition: bcd.h:107
bool bool_bcd(const BCD_int x)
Definition: bcd.h:1173
BCD_error
An enum that we use to track errors in BCD integers.
Definition: bcd.h:47
def digits
Definition: p0052.py:20
packed_BCD_pair * data
the raw data of the integer, DO NOT modify directly
Definition: bcd.h:70
there wasn't an error
Definition: bcd.h:48
BCD_int mul_bcd_cint(const BCD_int x, const intmax_t y)
Definition: bcd.h:1728
BCD_int abs_bcd(const BCD_int x, const bool no_copy)
Definition: bcd.h:1187
you tried to divide by zero
Definition: bcd.h:60
comp_t
An enum that we return for BCD comparisons.
Definition: bcd.h:37
BCD_int inc_bcd(const BCD_int x)
Definition: bcd.h:1294
bool negative
indicates the integer is negative
Definition: bcd.h:80
void ishift_bcd_left(BCD_int *const x, const size_t tens)
Definition: bcd.h:1901
void print_bcd(const BCD_int x)
Definition: bcd.h:1926
void print_bcd_ln(const BCD_int x)
Definition: bcd.h:1944
x > y
Definition: bcd.h:39
comp_t cmp_bcd_cuint(const BCD_int x, const uintmax_t y)
Definition: bcd.h:1709
BCD_int shift_bcd_left(const BCD_int x, const size_t tens)
Definition: bcd.h:1815
x == y
Definition: bcd.h:38
you tried to get the factorial of NaN
Definition: bcd.h:56
BCD_int pow_bcd(const BCD_int x, const BCD_int y)
Definition: bcd.h:1544
you tried to multiply NaN
Definition: bcd.h:53
void ineg_bcd(BCD_int *const x)
Definition: bcd.h:1606
you tried to use NaN as an exponent or base
Definition: bcd.h:55
void idiv_bcd_pow_10(BCD_int *const a, const size_t tens)
Definition: bcd.h:1905
BCD_int mod_bcd(const BCD_int x, const BCD_int y)
Definition: bcd.h:1476
BCD_int opp_bcd(const BCD_int x, const bool no_copy)
Definition: bcd.h:1195
comp_t cmp_bcd_cint(const BCD_int x, const intmax_t y)
Definition: bcd.h:1697
BCD_int mul_bcd_pow_10(const BCD_int x, const size_t tens)
Definition: bcd.h:1770
#define MAX_POW_10_64
This macro denotes the largest power of 10 that can be stored in a 64-bit unsigned integer...
Definition: math.h:212
BCD_int BCD_from_ascii(const char *const str, const size_t digits, const bool negative)
Definition: bcd.h:1124
BCD_int new_BCD_int1(const intmax_t a)
Definition: bcd.h:1050
you tried to shift NaN
Definition: bcd.h:57
BCD_int new_BCD_int2(uintmax_t a, const bool negative)
Definition: bcd.h:1056
BCD_int copy_BCD_int(BCD_int a)
Definition: bcd.h:1074
you tried to subtract NaN
Definition: bcd.h:52
void iinc_bcd(BCD_int *const x)
Definition: bcd.h:1620
Definition: __init__.py:1
uintmax_t abs_bcd_cuint(const BCD_int x)
Definition: bcd.h:1676
void imul_bcd(BCD_int *const x, const BCD_int y)
Definition: bcd.h:1638
BCD_int pow_cuint_cuint(const uintmax_t x, uintmax_t y)
Definition: bcd.h:1865
#define POW_OF_MAX_POW_10_64
This macro defines the power of MAX_POW_10_64.
Definition: math.h:217
size_t bcd_digits
the byte count of data
Definition: bcd.h:71
bool not_bcd(const BCD_int x)
Definition: bcd.h:1177
BCD_int neg_bcd(const BCD_int x, const bool no_copy)
Definition: bcd.h:1191
void imul_bcd_pow_10(BCD_int *const x, const size_t tens)
Definition: bcd.h:1895
BCD_int div_bcd_pow_10(const BCD_int a, const size_t tens)
Definition: bcd.h:1819
BCD_int dec_bcd(const BCD_int x)
Definition: bcd.h:1399
void idec_bcd(BCD_int *const x)
Definition: bcd.h:1632
void ishift_bcd_right(BCD_int *const a, const size_t tens)
Definition: bcd.h:1911
you are out of memory to make new ints
Definition: bcd.h:61
EXTERN_PRINTF
Definition: bcd.h:19
#define min(a, b)
Given two comparable variables, return the lesser.
Definition: macros.h:122
BCD_int factorial_bcd(const BCD_int x)
Definition: bcd.h:1579
this is the original NaN
Definition: bcd.h:49
you tried to get a negative factorial
Definition: bcd.h:59
you tried to use a negative exponent
Definition: bcd.h:58
x < y
Definition: bcd.h:40
void isign_bcd(BCD_int *const x, const bool negative)
Definition: bcd.h:1595
BCD_int add_bcd(const BCD_int x, const BCD_int y)
Definition: bcd.h:1199
A little-endian, arbitrary-precision, binary-coded-decimal number.
Definition: bcd.h:69
void isub_bcd(BCD_int *const x, const BCD_int y)
Definition: bcd.h:1626
x.nan || y.nan
Definition: bcd.h:41
uint8_t packed_BCD_pair
An alias for uint8_t that shows it is intended to store packed BCD data.
Definition: bcd.h:32
you tried to add NaN
Definition: bcd.h:51
#define PACK(decl)
Indicates to the compiler that the structure defined within should be packed bitwise.
Definition: math.h:160
#define unlikely(x)
Indicates to the compiler (if supported) that this branch is unlikely to occur and it should arrange ...
Definition: math.h:152
BCD_int BCD_from_bytes(const unsigned char *const str, const size_t chars, const bool negative, const bool little_endian)
Definition: bcd.h:1086
BCD_int div_bcd(const BCD_int x, const BCD_int y)
Definition: bcd.h:1472
const BCD_int BCD_nan
The BCD_nan constant is used to represent the commonly used value NaN.
Definition: bcd.h:122
BCD_int bcd_error(const BCD_error error, const BCD_error orig_error)
Definition: bcd.h:1141
void iopp_bcd(BCD_int *const x)
Definition: bcd.h:1610
BCD_int sub_bcd(const BCD_int x, const BCD_int y)
Definition: bcd.h:1298
BCD_int pow_cint_cuint(const intmax_t x, uintmax_t y)
Definition: bcd.h:1874
void ifactorial_bcd(BCD_int *const x)
Definition: bcd.h:1670
this BCD_int has been freed
Definition: bcd.h:50
reserved
Definition: bcd.h:63
uint8_t nan
indicates that the integer is NaN
Definition: bcd.h:74
intmax_t val_bcd_cint(const BCD_int x)
Definition: bcd.h:1688
bool even
indicates the integer is even
Definition: bcd.h:82
BCD_int mul_bcd_cuint(const BCD_int x, uintmax_t y)
Definition: bcd.h:1734
const BCD_int BCD_zero
The BCD_zero constant is used to represent the commonly used value zero.
Definition: bcd.h:115
BCD_int divmod_bcd(const BCD_int x, BCD_int y, BCD_int *mod)
Definition: bcd.h:1485
void iadd_bcd(BCD_int *const x, const BCD_int y)
Definition: bcd.h:1614