void ChangeConstants()

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;
    }
}