Fix bug in setting precomputed power-of-10

This commit is contained in:
2025-03-09 09:44:03 +03:00
parent fc3d4e22d5
commit 8009498331
2 changed files with 22 additions and 24 deletions

View File

@@ -26,8 +26,7 @@ static const uint8_t clzLookup[256] =
}; };
static const uint16_t pow10Data[] =
static const uint16_t pow10Data[] =
{ {
0x0001, 0x000A, 0x0064, 0x2710, 0xE100, 0x05F5, 0x0000, 0x6FC1, 0x0001, 0x000A, 0x0064, 0x2710, 0xE100, 0x05F5, 0x0000, 0x6FC1,
0x86F2, 0x0023, 0x0000, 0x0000, 0xEF81, 0x85AC, 0x415B, 0x2D6D, 0x86F2, 0x0023, 0x0000, 0x0000, 0xEF81, 0x85AC, 0x415B, 0x2D6D,
@@ -46,13 +45,13 @@ static const uint16_t pow10Data[] =
}; };
static const int pow10Index[] = static const int pow10Index[] =
{ {
0, 1, 2, 3, 4, 6, 10, 17, 31, 58, 0, 1, 2, 3, 4, 6, 10, 17, 31, 58,
}; };
static const int pow10Size[] = static const int pow10Size[] =
{ {
1, 1, 1, 1, 2, 4, 7, 14, 27, 54, 1, 1, 1, 1, 2, 4, 7, 14, 27, 54,
}; };
@@ -62,13 +61,13 @@ static void pow10Set(int index,
BH_Int1120 *out) BH_Int1120 *out)
{ {
out->size = pow10Size[index]; out->size = pow10Size[index];
memcpy(out->digits, pow10Data + pow10Index[index], out->size); memcpy(out->digits, pow10Data + pow10Index[index], out->size * sizeof(uint16_t));
} }
int BH_Int1120Clz(const uint16_t value) int BH_Int1120Clz(const uint16_t value)
{ {
if (value & 0xFF00) if (value & 0xFF00)
return clzLookup[(value >> 8) & 0xFF]; return clzLookup[(value >> 8) & 0xFF];
@@ -79,14 +78,14 @@ int BH_Int1120Clz(const uint16_t value)
int BH_Int1120Compare(const BH_Int1120 *a, int BH_Int1120Compare(const BH_Int1120 *a,
const BH_Int1120 *b) const BH_Int1120 *b)
{ {
int i, result; int i, result;
/* Compare by lengths */ /* Compare by lengths */
result = a->size - b->size; result = a->size - b->size;
if (result) if (result)
return result; return result;
/* Compare by blocks */ /* Compare by blocks */
for (i = a->size; i; i--) for (i = a->size; i; i--)
{ {
@@ -107,7 +106,7 @@ void BH_Int1120Add(const BH_Int1120 *a,
const BH_Int1120 *small, *big; const BH_Int1120 *small, *big;
uint32_t carry, tmp; uint32_t carry, tmp;
int i; int i;
small = b; small = b;
big = a; big = a;
@@ -117,7 +116,7 @@ void BH_Int1120Add(const BH_Int1120 *a,
/* Find smaller interger */ /* Find smaller interger */
if (a->size < b->size) if (a->size < b->size)
{ {
small = a; small = a;
big = b; big = b;
} }
@@ -141,7 +140,7 @@ void BH_Int1120Add(const BH_Int1120 *a,
/* Handle carry */ /* Handle carry */
if (carry) if (carry)
out->digits[i++] = carry; out->digits[i++] = carry;
out->size = i; out->size = i;
} }
@@ -169,7 +168,7 @@ void BH_Int1120Sub(const BH_Int1120 *a,
carry = (tmp >> 31) & 0x1; carry = (tmp >> 31) & 0x1;
out->digits[i] = tmp & 0xFFFF; out->digits[i] = tmp & 0xFFFF;
} }
/* Truncate length on empty blocks */ /* Truncate length on empty blocks */
out->size = a->size; out->size = a->size;
while(out->size && !out->digits[out->size - 1]) while(out->size && !out->digits[out->size - 1])
@@ -209,7 +208,7 @@ void BH_Int1120Mul(const BH_Int1120 *a,
out->digits[i + j] = tmp & 0xFFFF; out->digits[i + j] = tmp & 0xFFFF;
} }
} }
out->size = a->size + b->size; out->size = a->size + b->size;
if (!out->digits[out->size - 1]) if (!out->digits[out->size - 1])
out->size--; out->size--;
@@ -244,7 +243,7 @@ void BH_Int1120MulDigit(const BH_Int1120 *in,
tmp = (uint32_t)out->digits[i] + carry; tmp = (uint32_t)out->digits[i] + carry;
out->digits[i] = tmp & 0xFFFF; out->digits[i] = tmp & 0xFFFF;
} }
out->size = in->size + 1; out->size = in->size + 1;
if (!out->digits[out->size - 1]) if (!out->digits[out->size - 1])
out->size--; out->size--;
@@ -259,7 +258,7 @@ static uint16_t BH_Int1120DivGuess(const BH_Int1120 *a,
/* Compare two values */ /* Compare two values */
if (BH_Int1120Compare(a, b) < 0) if (BH_Int1120Compare(a, b) < 0)
return 0; return 0;
/* Make a guess */ /* Make a guess */
tmp = a->digits[a->size - 1]; tmp = a->digits[a->size - 1];
if (a->size != b->size) if (a->size != b->size)
@@ -307,20 +306,20 @@ void BH_Int1120Div(const BH_Int1120 *a,
/* If the guess was wrong - decrement guess and try again */ /* If the guess was wrong - decrement guess and try again */
while (BH_Int1120Compare(r, &tmp) < 0) while (BH_Int1120Compare(r, &tmp) < 0)
BH_Int1120MulDigit(&right, --guess, &tmp); BH_Int1120MulDigit(&right, --guess, &tmp);
/* Store digit in quotient */ /* Store digit in quotient */
BH_Int1120Lsh(q, 16, q); BH_Int1120Lsh(q, 16, q);
q->digits[0] = guess; q->digits[0] = guess;
if (!q->size) if (!q->size)
q->size = 1; q->size = 1;
/* Adjust remainder */ /* Adjust remainder */
BH_Int1120Sub(r, &tmp, r); BH_Int1120Sub(r, &tmp, r);
/* Fetch next digit or exit */ /* Fetch next digit or exit */
if (!left.size) if (!left.size)
break; break;
BH_Int1120Lsh(r, 16, r); BH_Int1120Lsh(r, 16, r);
r->digits[0] = left.digits[--left.size]; r->digits[0] = left.digits[--left.size];
if (!r->size) if (!r->size)
@@ -350,7 +349,7 @@ void BH_Int1120MulPow10(const BH_Int1120 *in,
BH_Int1120 *current, *next, *swap; BH_Int1120 *current, *next, *swap;
BH_Int1120 tmp[2], factor; BH_Int1120 tmp[2], factor;
int index; int index;
/* Make sure exponent is low, otherwise we get an overflow */ /* Make sure exponent is low, otherwise we get an overflow */
assert(exponent < 512); assert(exponent < 512);
@@ -464,7 +463,7 @@ void BH_Int1120Rsh(const BH_Int1120 *in,
/* Shift and copy parts of two blocks */ /* Shift and copy parts of two blocks */
low = in->digits[blocks] >> bits; low = in->digits[blocks] >> bits;
high = in->digits[blocks + 1] << (16 - bits); high = in->digits[blocks + 1] << (16 - bits);
for (i = 0; i < in->size - blocks - 2; i++) for (i = 0; i < in->size - blocks - 2; i++)
{ {
out->digits[i] = low | high; out->digits[i] = low | high;

View File

@@ -25,7 +25,6 @@ typedef struct BH_Int1120
int BH_Int1120Clz(const uint16_t value); int BH_Int1120Clz(const uint16_t value);
/** /**
* Compares big integers \a a and \a b. * Compares big integers \a a and \a b.
* *
@@ -89,7 +88,7 @@ void BH_Int1120MulDigit(const BH_Int1120 *in,
/** /**
* Divides two big integers \a a and \a b and stores quotient into \a q and * Divides two big integers \a a and \a b and stores quotient into \a q and
* remainder into \a r. * remainder into \a r.
* *
* \param a A integer * \param a A integer
@@ -136,7 +135,7 @@ void BH_Int1120Pow2(int exponent,
/** /**
* Left shifts big integer \a in by \a amount places and stores result into * Left shifts big integer \a in by \a amount places and stores result into
* \a out. * \a out.
* *
* \param in Input integer * \param in Input integer