in src/CalcManager/Ratpack/support.cpp [133:286]
void ChangeConstants(uint32_t radix, int32_t precision)
{
// ratio is set to the number of digits in the current radix, you can get
// in the internal BASEX radix, this is important for length calculations
// in translating from radix to BASEX and back.
uint64_t limit = static_cast<uint64_t>(BASEX) / static_cast<uint64_t>(radix);
g_ratio = 0;
for (uint32_t digit = 1; digit < limit; digit *= radix)
{
g_ratio++;
}
g_ratio += !g_ratio;
destroyrat(rat_nRadix);
rat_nRadix = i32torat(radix);
// Check to see what we have to recalculate and what we don't
if (cbitsofprecision < (g_ratio * static_cast<int32_t>(radix) * precision))
{
g_ftrueinfinite = false;
INIT_AND_DUMP_RAW_NUM_IF_NULL(num_one, 1L);
INIT_AND_DUMP_RAW_NUM_IF_NULL(num_two, 2L);
INIT_AND_DUMP_RAW_NUM_IF_NULL(num_five, 5L);
INIT_AND_DUMP_RAW_NUM_IF_NULL(num_six, 6L);
INIT_AND_DUMP_RAW_NUM_IF_NULL(num_ten, 10L);
INIT_AND_DUMP_RAW_RAT_IF_NULL(rat_six, 6L);
INIT_AND_DUMP_RAW_RAT_IF_NULL(rat_two, 2L);
INIT_AND_DUMP_RAW_RAT_IF_NULL(rat_zero, 0L);
INIT_AND_DUMP_RAW_RAT_IF_NULL(rat_one, 1L);
INIT_AND_DUMP_RAW_RAT_IF_NULL(rat_neg_one, -1L);
INIT_AND_DUMP_RAW_RAT_IF_NULL(rat_ten, 10L);
INIT_AND_DUMP_RAW_RAT_IF_NULL(rat_word, 0xffff);
INIT_AND_DUMP_RAW_RAT_IF_NULL(rat_word, 0xff);
INIT_AND_DUMP_RAW_RAT_IF_NULL(rat_400, 400);
INIT_AND_DUMP_RAW_RAT_IF_NULL(rat_360, 360);
INIT_AND_DUMP_RAW_RAT_IF_NULL(rat_200, 200);
INIT_AND_DUMP_RAW_RAT_IF_NULL(rat_180, 180);
INIT_AND_DUMP_RAW_RAT_IF_NULL(rat_max_exp, 100000);
// 3248, is the max number for which calc is able to compute factorial, after that it is unable to compute due to overflow.
// Hence restricted factorial range as at most 3248.Beyond that calc will throw overflow error immediately.
INIT_AND_DUMP_RAW_RAT_IF_NULL(rat_max_fact, 3249);
// -1000, is the min number for which calc is able to compute factorial, after that it takes too long to compute.
INIT_AND_DUMP_RAW_RAT_IF_NULL(rat_min_fact, -1000);
DUPRAT(rat_smallest, rat_nRadix);
ratpowi32(&rat_smallest, -precision, precision);
DUPRAT(rat_negsmallest, rat_smallest);
rat_negsmallest->pp->sign = -1;
DUMPRAWRAT(rat_smallest);
DUMPRAWRAT(rat_negsmallest);
if (rat_half == nullptr)
{
createrat(rat_half);
DUPNUM(rat_half->pp, num_one);
DUPNUM(rat_half->pq, num_two);
DUMPRAWRAT(rat_half);
}
if (pt_eight_five == nullptr)
{
createrat(pt_eight_five);
pt_eight_five->pp = i32tonum(85L, BASEX);
pt_eight_five->pq = i32tonum(100L, BASEX);
DUMPRAWRAT(pt_eight_five);
}
DUPRAT(rat_qword, rat_two);
numpowi32(&(rat_qword->pp), 64, BASEX, precision);
subrat(&rat_qword, rat_one, precision);
DUMPRAWRAT(rat_qword);
DUPRAT(rat_dword, rat_two);
numpowi32(&(rat_dword->pp), 32, BASEX, precision);
subrat(&rat_dword, rat_one, precision);
DUMPRAWRAT(rat_dword);
DUPRAT(rat_max_i32, rat_two);
numpowi32(&(rat_max_i32->pp), 31, BASEX, precision);
DUPRAT(rat_min_i32, rat_max_i32);
subrat(&rat_max_i32, rat_one, precision); // rat_max_i32 = 2^31 -1
DUMPRAWRAT(rat_max_i32);
rat_min_i32->pp->sign *= -1; // rat_min_i32 = -2^31
DUMPRAWRAT(rat_min_i32);
DUPRAT(rat_min_exp, rat_max_exp);
rat_min_exp->pp->sign *= -1;
DUMPRAWRAT(rat_min_exp);
cbitsofprecision = g_ratio * radix * precision;
// Apparently when dividing 180 by pi, another (internal) digit of
// precision is needed.
int32_t extraPrecision = precision + g_ratio;
DUPRAT(pi, rat_half);
asinrat(&pi, radix, extraPrecision);
mulrat(&pi, rat_six, extraPrecision);
DUMPRAWRAT(pi);
DUPRAT(two_pi, pi);
DUPRAT(pi_over_two, pi);
DUPRAT(one_pt_five_pi, pi);
addrat(&two_pi, pi, extraPrecision);
DUMPRAWRAT(two_pi);
divrat(&pi_over_two, rat_two, extraPrecision);
DUMPRAWRAT(pi_over_two);
addrat(&one_pt_five_pi, pi_over_two, extraPrecision);
DUMPRAWRAT(one_pt_five_pi);
DUPRAT(e_to_one_half, rat_half);
_exprat(&e_to_one_half, extraPrecision);
DUMPRAWRAT(e_to_one_half);
DUPRAT(rat_exp, rat_one);
_exprat(&rat_exp, extraPrecision);
DUMPRAWRAT(rat_exp);
// WARNING: remember lograt uses exponent constants calculated above...
DUPRAT(ln_ten, rat_ten);
lograt(&ln_ten, extraPrecision);
DUMPRAWRAT(ln_ten);
DUPRAT(ln_two, rat_two);
lograt(&ln_two, extraPrecision);
DUMPRAWRAT(ln_two);
destroyrat(rad_to_deg);
rad_to_deg = i32torat(180L);
divrat(&rad_to_deg, pi, extraPrecision);
DUMPRAWRAT(rad_to_deg);
destroyrat(rad_to_grad);
rad_to_grad = i32torat(200L);
divrat(&rad_to_grad, pi, extraPrecision);
DUMPRAWRAT(rad_to_grad);
}
else
{
_readconstants();
DUPRAT(rat_smallest, rat_nRadix);
ratpowi32(&rat_smallest, -precision, precision);
DUPRAT(rat_negsmallest, rat_smallest);
rat_negsmallest->pp->sign = -1;
}
}