Skip to content

IntPow

Description

Generic exponentiation convenience macro.

Parameters

Name Direction Description
result out Destination for the result
base in Base value
exponent in Exponent selected through generic dispatch

Usage example (from documentation)

  IntPow(&power, &base, 20u);

Success

Returns true; *result holds base ** exponent computed via repeated-squaring.

Failure

Returns false if an intermediate allocation fails or if exponent is negative; *result is unchanged.

Usage example (Cross-references)

Usage examples (Cross-references)
            Int pow5 = IntInit(alloc);
            Int sig  = IntInit(alloc);
            if (!int_try_from_u64(&five, 5u, alloc) || !IntPow(&pow5, &five, n) ||
                !int_mul(&sig, &out->significand, &pow5)) {
                IntDeinit(&five);
    
    bool test_int_pow_generic(void) {
        WriteFmt("Testing IntPow generic dispatch\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
        Str text         = StrInit(&alloc.base);
    
        IntPow(&result_value, &base, 20u);
        text        = IntToStr(&result_value);
        bool result = ZstrCompare(StrBegin(&text), "79792266297612001") == 0;
    
        StrDeinit(&text);
        IntPow(&result_value, &base, &exponent);
        text   = IntToStr(&result_value);
        result = result && (ZstrCompare(StrBegin(&text), "79792266297612001") == 0);
    
        // exponent 0 -> 1 (loop body never runs)
        IntPow(&result, &base, 0u);
        bool ok = IntToU64(&result) == 1;
    
        // exponent 1 -> base (one odd bit, no squaring)
        IntPow(&result, &base, 1u);
        ok = ok && (IntToU64(&result) == 7);
    
        // exponent 2 -> 49 (squaring path)
        IntPow(&result, &base, 2u);
        ok = ok && (IntToU64(&result) == 49);
    
        // exponent 5 -> 16807 (mixed odd/even bits)
        IntPow(&result, &base, 5u);
        ok = ok && (IntToU64(&result) == 16807);
    //    exponent the real code must take the int_pow_u64 path and return true.
    bool test_m22_pow_int_exponent_value(void) {
        WriteFmt("Testing IntPow with an Int exponent (small, exact value)\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        // 7**5 == 16807.
        bool ok     = IntPow(&power, &base, &exp);
        bool result = ok;
        result      = result && (IntToU64(&power) == 16807u);
    // exponent through IntToU64) and not return the clean false.
    bool test_m22_pow_int_exponent_too_large(void) {
        WriteFmt("Testing IntPow rejects an exponent that overflows u64\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
        Int sentinel = IntFrom(123, &alloc.base);
    
        bool rejected = !IntPow(&power, &base, &exp);
        // Result must be left untouched on rejection.
        bool result = rejected && (IntCompare(&power, &sentinel) == 0);
        Int result_value = IntFrom(99, &alloc.base);
    
        bool ok     = IntPow(&result_value, &base, (i64)4);
        bool result = ok && (IntToU64(&result_value) == 81);
        Int result_value = IntFrom(99, &alloc.base);
    
        bool ok     = IntPow(&result_value, &base, (i64)0);
        bool result = ok && (IntToU64(&result_value) == 1);
        Int r    = IntFrom(7u, a);
    
        bool ok = IntPow(&r, &base, 13u);
        ok      = ok && IntToU64(&r) == 1594323u; // 3^13
Last updated on