15typedef enum : uint8_t {
20typedef enum : int32_t {
48 memset(big, 0,
sizeof(*big));
49 big->
word[0] = (uint32_t)value;
50 big->
word[1] = (uint32_t)(value >> 32U);
51 big->
used = (uint8_t)((big->
word[1] != 0U) ? 2U : 1U);
63 while ((big->
used > 1U) && (big->
word[big->
used - 1U] == 0U)) {
77 if ((big->
used == 1U) && (big->
word[0] == 0U)) {
80 uint32_t high = big->
word[big->
used - 1U];
86 return (uint16_t)(((uint16_t)(big->
used - 1U) * 32U) + bits);
99 for (uint8_t i = 0U; i < big->
used; ++i) {
100 const uint64_t product = ((uint64_t)big->
word[i] * factor) + carry;
101 big->
word[i] = (uint32_t)product;
102 carry = product >> 32U;
108 big->
word[big->
used] = (uint32_t)carry;
124 const uint16_t words = shift / 32U;
125 const uint8_t bits = (uint8_t)(shift % 32U);
129 memset(dst, 0,
sizeof(*dst));
131 for (uint8_t i = 0U; i < src->
used; ++i) {
132 const uint64_t value = ((uint64_t)src->
word[i] << bits) | carry;
133 dst->
word[(uint16_t)i + words] = (uint32_t)value;
134 carry = value >> 32U;
136 dst->
used = (uint8_t)((uint16_t)src->
used + words);
138 dst->
word[dst->
used] = (uint32_t)carry;
156 return lhs->
used > rhs->
used ? 1 : -1;
158 for (uint8_t i = lhs->
used; i > 0U; --i) {
159 if (lhs->
word[i - 1U] != rhs->
word[i - 1U]) {
160 return lhs->
word[i - 1U] > rhs->
word[i - 1U] ? 1 : -1;
176 uint64_t borrow = 0U;
177 for (uint8_t i = 0U; i < lhs->
used; ++i) {
178 const uint64_t subtrahend = (uint64_t)(i < rhs->used ? rhs->
word[i] : 0U) + borrow;
179 const uint64_t current = lhs->
word[i];
180 lhs->
word[i] = (uint32_t)(current - subtrahend);
181 borrow = current < subtrahend ? 1U : 0U;
195 int32_t binary_scale,
199 const int32_t shift = binary_scale - exponent;
221 int32_t binary_shift,
226 if (binary_shift >= 0) {
230 divisor = *denominator;
237 uint64_t quotient = 0U;
243 for (int32_t bit = top; bit >= 0; --bit) {
250 quotient |= UINT64_C(1) << (uint32_t)bit;
258 if ((comparison > 0) || ((comparison == 0) && ((quotient & 1U) != 0U))) {
273 int32_t decimal_scale,
279 const uint32_t count = (uint32_t)(decimal_scale < 0 ? -decimal_scale : decimal_scale);
281 for (uint32_t i = 0U; i < count; ++i) {
316 if ((quotient == 0U) ||
326 memcpy(out, &bits,
sizeof(bits));
331 int32_t decimal_scale,
339 if (mantissa == 0U) {
341 memcpy(out, &bits,
sizeof(bits));
358 const int32_t shift = normal
361 uint64_t quotient = 0U;
mdl_state_big_limit_t
Fixed storage is sufficient for 17 digits multiplied or divided by 10^400.
@ k_state_big_words
Capacity of one fixed unsigned integer.
static void internal_mdl_state_big_init(mdl_state_big_t *big, uint64_t value)
Initialize a fixed integer from one uint64 value.
static bool internal_mdl_state_big_mul(mdl_state_big_t *big, uint32_t factor)
Multiply a fixed integer by one small factor.
static int internal_mdl_state_big_compare(const mdl_state_big_t *lhs, const mdl_state_big_t *rhs)
Compare two normalized fixed integers.
static void internal_mdl_state_big_trim(mdl_state_big_t *big)
Remove unused high words while retaining one zero word.
mdl_state_decimal_limit_t
Exact decimal and binary64 representation constants.
@ k_state_binary64_exponent_bias
Binary64 exponent bias.
@ k_state_binary64_exponent_max
Largest finite unbiased exponent.
@ k_state_binary64_fraction_bits
Stored binary64 fraction width.
@ k_state_binary64_exponent_min
Smallest normal unbiased exponent.
@ k_state_decimal_scale_max
Accepted absolute decimal scale.
@ k_state_binary64_subnormal_scale
Scale selecting subnormal units.
@ k_state_binary64_precision_bits
Binary64 significand precision.
@ k_state_binary64_sign_shift
Binary64 sign-bit position.
@ k_state_divide_bits
Width of the bounded quotient.
@ k_state_decimal_prime
Odd factor of decimal radix.
static bool internal_mdl_state_build_rational(uint64_t mantissa, int32_t decimal_scale, mdl_state_big_t *numerator, mdl_state_big_t *denominator)
Build the odd rational factors for a decimal value.
static uint16_t internal_mdl_state_big_bits(const mdl_state_big_t *big)
Return the significant bit count of a fixed integer.
static bool internal_mdl_state_encode(uint64_t quotient, int32_t exponent, bool negative, bool normal, double *out)
Encode one rounded quotient as finite binary64.
static bool internal_mdl_state_divide(const mdl_state_big_t *numerator, const mdl_state_big_t *denominator, int32_t binary_shift, uint64_t *out)
Divide one scaled rational and round to nearest-even.
static int internal_mdl_state_compare_power(const mdl_state_big_t *numerator, const mdl_state_big_t *denominator, int32_t binary_scale, int32_t exponent)
Compare a scaled rational against one exact power of two.
static bool internal_mdl_state_big_shift(const mdl_state_big_t *src, uint16_t shift, mdl_state_big_t *dst)
Copy one fixed integer shifted left by an exact bit count.
static void internal_mdl_state_big_subtract(mdl_state_big_t *lhs, const mdl_state_big_t *rhs)
Subtract a no-larger fixed integer from another.
bool priv_mdl_state_decimal_to_binary64(uint64_t mantissa, int32_t decimal_scale, bool negative, double *out)
Convert one exact bounded decimal rational to binary64.
Module-private validation shared by the state model and codec.
Annotation-attribute framework macros for ra8-firmware.
#define RA8_PRIV
Module-private helper: shared across TUs but only inside one library.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
void * memset(void *dst, int value, size_t n)
Fill memory with a constant byte value.
void * memcpy(void *dst, const void *src, size_t n)
Copy memory area between non-overlapping regions.
Little-endian base-2^32 unsigned integer.
uint8_t used
Significant word count.
uint32_t word[k_state_big_words]
Little-endian magnitude words.