const long LIMB_MODULUS   = 1000000000000000000L;            // == 10^18
    public static int digit_sum_for_power_of_2(int power_of_2)
    {
        Trace.Assert(power_of_2 > 0);
        int total_digits = (int)Math.Ceiling(Math.Log10(2) * power_of_2);
        int total_limbs  = (total_digits + DIGITS_PER_LIMB - 1) / DIGITS_PER_LIMB;
        var a            = new long[total_limbs];
        int limbs        = 1;

        a[0] = 2;
        for (int i = 1; i < power_of_2; ++i)
        {
            int carry = 0;
            for (int j = 0; j < limbs; ++j)
            {
                long new_limb = (a[j] << 1) | carry;
                carry = 0;
                if (new_limb >= LIMB_MODULUS)
                {
                    new_limb -= LIMB_MODULUS;
                    carry     = 1;
                }
                a[j] = new_limb;
            }
            if (carry != 0)
            {
                a[limbs++] = carry;
            }
        }
        return(E16_Common.digit_sum(a));
    }
예제 #2
0
    public static int digit_sum_for_power_of_2(int e)
    {
        Trace.Assert(e > 0);
        int total_digits  = (int)Math.Ceiling(Math.Log10(2) * e);
        int total_limbs   = (total_digits + DIGITS_PER_LIMB - 1) / DIGITS_PER_LIMB;
        var squared_power = new List <int>(total_limbs)
        {
            2
        };
        var result = new List <int>(total_limbs);

        result.Add((e & 1) == 0 ? 1 : 2);
        while ((e >>= 1) != 0)
        {
            squared_power = multiply(squared_power, squared_power);
            if ((e & 1) == 1)
            {
                result = multiply(result, squared_power);
            }
        }
        return(E16_Common.digit_sum(result));
    }