Fix bug in setting precomputed power-of-10
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user