in kotlin-native/runtime/src/main/cpp/dtoa/dblparse.cpp [701:884]
void Kotlin_native_NumberConverter_bigIntDigitGeneratorInstImpl (KRef results,
KRef uArray,
KLong f,
KInt e,
KBoolean isDenormalized,
KBoolean mantissaIsZero,
KInt p)
{
int RLength, SLength, TempLength, mplus_Length, mminus_Length;
int high, low, i;
int k, firstK, U;
int getCount, setCount;
U_64 R[RM_SIZE], S[STemp_SIZE], mplus[RM_SIZE], mminus[RM_SIZE], Temp[STemp_SIZE];
memset (R, 0, RM_SIZE * sizeof (U_64));
memset (S, 0, STemp_SIZE * sizeof (U_64));
memset (mplus, 0, RM_SIZE * sizeof (U_64));
memset (mminus, 0, RM_SIZE * sizeof (U_64));
memset (Temp, 0, STemp_SIZE * sizeof (U_64));
if (e >= 0)
{
*R = f;
*mplus = *mminus = 1;
simpleShiftLeftHighPrecision (mminus, RM_SIZE, e);
if (f != (2 << (p - 1)))
{
simpleShiftLeftHighPrecision (R, RM_SIZE, e + 1);
*S = 2;
/*
* m+ = m+ << e results in 1.0e23 to be printed as
* 0.9999999999999999E23
* m+ = m+ << e+1 results in 1.0e23 to be printed as
* 1.0e23 (caused too much rounding)
* 470fffffffffffff = 2.0769187434139308E34
* 4710000000000000 = 2.076918743413931E34
*/
simpleShiftLeftHighPrecision (mplus, RM_SIZE, e);
}
else
{
simpleShiftLeftHighPrecision (R, RM_SIZE, e + 2);
*S = 4;
simpleShiftLeftHighPrecision (mplus, RM_SIZE, e + 1);
}
}
else
{
if (isDenormalized || (f != (2 << (p - 1))))
{
*R = f << 1;
*S = 1;
simpleShiftLeftHighPrecision (S, STemp_SIZE, 1 - e);
*mplus = *mminus = 1;
}
else
{
*R = f << 2;
*S = 1;
simpleShiftLeftHighPrecision (S, STemp_SIZE, 2 - e);
*mplus = 2;
*mminus = 1;
}
}
k = (int) ceil ((e + p - 1) * INV_LOG_OF_TEN_BASE_2 - 1e-10);
if (k > 0)
{
timesTenToTheEHighPrecision (S, STemp_SIZE, k);
}
else
{
timesTenToTheEHighPrecision (R, RM_SIZE, -k);
timesTenToTheEHighPrecision (mplus, RM_SIZE, -k);
timesTenToTheEHighPrecision (mminus, RM_SIZE, -k);
}
RLength = mplus_Length = mminus_Length = RM_SIZE;
SLength = TempLength = STemp_SIZE;
memset (Temp + RM_SIZE, 0, (STemp_SIZE - RM_SIZE) * sizeof (U_64));
memcpy (Temp, R, RM_SIZE * sizeof (U_64));
while (RLength > 1 && R[RLength - 1] == 0)
--RLength;
while (mplus_Length > 1 && mplus[mplus_Length - 1] == 0)
--mplus_Length;
while (mminus_Length > 1 && mminus[mminus_Length - 1] == 0)
--mminus_Length;
while (SLength > 1 && S[SLength - 1] == 0)
--SLength;
TempLength = (RLength > mplus_Length ? RLength : mplus_Length) + 1;
addHighPrecision (Temp, TempLength, mplus, mplus_Length);
if (compareHighPrecision (Temp, TempLength, S, SLength) >= 0)
{
firstK = k;
}
else
{
firstK = k - 1;
simpleAppendDecimalDigitHighPrecision (R, ++RLength, 0);
simpleAppendDecimalDigitHighPrecision (mplus, ++mplus_Length, 0);
simpleAppendDecimalDigitHighPrecision (mminus, ++mminus_Length, 0);
while (RLength > 1 && R[RLength - 1] == 0)
--RLength;
while (mplus_Length > 1 && mplus[mplus_Length - 1] == 0)
--mplus_Length;
while (mminus_Length > 1 && mminus[mminus_Length - 1] == 0)
--mminus_Length;
}
getCount = setCount = 0;
do
{
U = 0;
for (i = 3; i >= 0; --i)
{
TempLength = SLength + 1;
Temp[SLength] = 0;
memcpy (Temp, S, SLength * sizeof (U_64));
simpleShiftLeftHighPrecision (Temp, TempLength, i);
if (compareHighPrecision (R, RLength, Temp, TempLength) >= 0)
{
subtractHighPrecision (R, RLength, Temp, TempLength);
U += 1 << i;
}
}
low = compareHighPrecision (R, RLength, mminus, mminus_Length) <= 0;
memset (Temp + RLength, 0, (STemp_SIZE - RLength) * sizeof (U_64));
memcpy (Temp, R, RLength * sizeof (U_64));
TempLength = (RLength > mplus_Length ? RLength : mplus_Length) + 1;
addHighPrecision (Temp, TempLength, mplus, mplus_Length);
high = compareHighPrecision (Temp, TempLength, S, SLength) >= 0;
if (low || high)
break;
simpleAppendDecimalDigitHighPrecision (R, ++RLength, 0);
simpleAppendDecimalDigitHighPrecision (mplus, ++mplus_Length, 0);
simpleAppendDecimalDigitHighPrecision (mminus, ++mminus_Length, 0);
while (RLength > 1 && R[RLength - 1] == 0)
--RLength;
while (mplus_Length > 1 && mplus[mplus_Length - 1] == 0)
--mplus_Length;
while (mminus_Length > 1 && mminus[mminus_Length - 1] == 0)
--mminus_Length;
Kotlin_IntArray_set(uArray, setCount++, U);
//uArray[setCount++] = U;
}
while (1);
simpleShiftLeftHighPrecision (R, ++RLength, 1);
if (low && !high)
Kotlin_IntArray_set(uArray, setCount++, U);
//uArray[setCount++] = U;
else if (high && !low)
Kotlin_IntArray_set(uArray, setCount++, U + 1);
//uArray[setCount++] = U + 1;
else if (compareHighPrecision (R, RLength, S, SLength) < 0)
Kotlin_IntArray_set(uArray, setCount++, U);
//uArray[setCount++] = U;
else
Kotlin_IntArray_set(uArray, setCount++, U + 1);
//uArray[setCount++] = U + 1;
Kotlin_IntArray_set(results, 0, setCount);
// fid = (*env)->GetFieldID (env, clazz, "setCount", "I");
// (*env)->SetIntField (env, inst, fid, setCount);
Kotlin_IntArray_set(results, 1, getCount);
// fid = (*env)->GetFieldID (env, clazz, "getCount", "I");
// (*env)->SetIntField (env, inst, fid, getCount);
Kotlin_IntArray_set(results, 2, firstK);
// fid = (*env)->GetFieldID (env, clazz, "firstK", "I");
// (*env)->SetIntField (env, inst, fid, firstK);
}