Skip to content

IntCompare

Description

Compare an integer against another integer-like value. Dispatches on the type of rhs to the matching internal handler.

Parameters

Name Direction Description
lhs in Left-hand integer
rhs in Right-hand operand (Int, pointer, u64, or i64 compatible type)

Usage example (from documentation)

  int cmp = IntCompare(&value, 42);

Success

Returns -1 if lhs < rhs, 0 if equal, 1 if lhs > rhs.

Failure

Pure comparison cannot fail. LOG_FATAL if either operand pointer is NULL (propagated from the underlying handler’s ValidateInt).

Usage example (Cross-references)

Usage examples (Cross-references)
    /// TAGS: Int, Compare, Equal, Generic
    ///
    #    define IntEQ(lhs, rhs) (IntCompare((lhs), (rhs)) == 0)
    ///
    /// Test whether `lhs` is strictly less than `rhs`.
    /// TAGS: Int, Compare, LessThan, Generic
    ///
    #    define IntLT(lhs, rhs) (IntCompare((lhs), (rhs)) < 0)
    ///
    /// Test whether `lhs` is less than or equal to `rhs`.
    /// TAGS: Int, Compare, LessEqual, Generic
    ///
    #    define IntLE(lhs, rhs) (IntCompare((lhs), (rhs)) <= 0)
    ///
    /// Test whether `lhs` is strictly greater than `rhs`.
    /// TAGS: Int, Compare, GreaterThan, Generic
    ///
    #    define IntGT(lhs, rhs) (IntCompare((lhs), (rhs)) > 0)
    ///
    /// Test whether `lhs` is greater than or equal to `rhs`.
    /// TAGS: Int, Compare, GreaterEqual, Generic
    ///
    #    define IntGE(lhs, rhs) (IntCompare((lhs), (rhs)) >= 0)
    ///
    /// Test whether two numeric values differ.
    /// TAGS: Int, Compare, NotEqual, Generic
    ///
    #    define IntNE(lhs, rhs) (IntCompare((lhs), (rhs)) != 0)
    #endif
    
    bool test_int_compare(void) {
        WriteFmt("Testing IntCompare\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
        Int c = IntFromBinary("000101010", &alloc.base);
    
        bool result = IntCompare(&a, &b) < 0;
        result      = result && (IntCompare(&b, &a) > 0);
        result      = result && (IntCompare(&b, &c) == 0);
    
        bool result = IntCompare(&a, &b) < 0;
        result      = result && (IntCompare(&b, &a) > 0);
        result      = result && (IntCompare(&b, &c) == 0);
        bool result = IntCompare(&a, &b) < 0;
        result      = result && (IntCompare(&b, &a) > 0);
        result      = result && (IntCompare(&b, &c) == 0);
    
        IntDeinit(&a);
    
    bool test_int_compare_generic(void) {
        WriteFmt("Testing IntCompare generic dispatch\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntShiftLeft(&big, 80);
    
        bool result = (IntCompare(&value, &same) == 0);
        result      = result && (IntCompare(&value, &same) == 0);
        result      = result && (IntCompare(&value, 42) == 0);
    
        bool result = (IntCompare(&value, &same) == 0);
        result      = result && (IntCompare(&value, &same) == 0);
        result      = result && (IntCompare(&value, 42) == 0);
        result      = result && (IntCompare(&value, 100ULL) < 0);
        bool result = (IntCompare(&value, &same) == 0);
        result      = result && (IntCompare(&value, &same) == 0);
        result      = result && (IntCompare(&value, 42) == 0);
        result      = result && (IntCompare(&value, 100ULL) < 0);
        result      = result && (IntCompare(&value, -1) > 0);
        result      = result && (IntCompare(&value, &same) == 0);
        result      = result && (IntCompare(&value, 42) == 0);
        result      = result && (IntCompare(&value, 100ULL) < 0);
        result      = result && (IntCompare(&value, -1) > 0);
        result      = result && (IntCompare(&big, UINT64_MAX) > 0);
        result      = result && (IntCompare(&value, 42) == 0);
        result      = result && (IntCompare(&value, 100ULL) < 0);
        result      = result && (IntCompare(&value, -1) > 0);
        result      = result && (IntCompare(&big, UINT64_MAX) > 0);
        result      = result && IntEQ(&value, 42);
        result      = result && (IntCompare(&value, 100ULL) < 0);
        result      = result && (IntCompare(&value, -1) > 0);
        result      = result && (IntCompare(&big, UINT64_MAX) > 0);
        result      = result && IntEQ(&value, 42);
        result      = result && IntLE(&value, 42);
    // ---------------------------------------------------------------------------
    bool test_m24_compare_u64_64bit_equal(void) {
        WriteFmt("Testing IntCompare(2^63, 2^63) == 0\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        bool fail = (IntBitLength(&lhs) != 64); // sanity: exactly 64 bits.
        fail      = fail || (IntCompare(&lhs, 0x8000000000000000u) != 0);
    
        IntDeinit(&lhs);
    // `lhs_value < rhs` branch alongside the wide-value guard.
    bool test_m24_compare_u64_below(void) {
        WriteFmt("Testing IntCompare(7, 9) == -1\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
        Int lhs = IntFrom(7u, &alloc.base);
    
        bool fail = (IntCompare(&lhs, 9u) != -1);
    
        IntDeinit(&lhs);
    
        IntModMul(&check, &result_value, &b, &m);
        result = result && (IntCompare(&check, 10) == 0);
    
        IntDeinit(&a);
        bool result = IntModSqrt(&root, &value, &mod);
        IntSquareMod(&check, &root, &mod);
        result = result && (IntCompare(&check, 10) == 0);
    
        IntDeinit(&value);
    
        bool result = !IntModSqrt(&root, &value, &mod);
        result      = result && (IntCompare(&root, 99) == 0);
    
        IntDeinit(&value);
    
        bool result = !IntModDiv(&result_value, &a, &b, &m);
        result      = result && (IntCompare(&result_value, 99) == 0);
    
        IntDeinit(&a);
        bool result = !IntDivMod(&quotient, &remainder, &dividend, &divisor);
    
        result = result && (IntCompare(&quotient, 99) == 0);
        result = result && (IntCompare(&remainder, 77) == 0);
    
        result = result && (IntCompare(&quotient, 99) == 0);
        result = result && (IntCompare(&remainder, 77) == 0);
    
        IntDeinit(&dividend);
        bool result    = !IntRootRem(&root, &remainder, &value, 0);
    
        result = result && (IntCompare(&root, 99) == 0);
        result = result && (IntCompare(&remainder, 77) == 0);
    
        result = result && (IntCompare(&root, 99) == 0);
        result = result && (IntCompare(&remainder, 77) == 0);
    
        IntDeinit(&value);
    
        IntDiv(&quotient, &dividend, 0u);
        bool result = IntCompare(&quotient, 99) == 0;
    
        IntDeinit(&dividend);
    
        IntMod(&result_value, &value, 0u);
        bool result = IntCompare(&result_value, 99) == 0;
    
        IntDeinit(&value);
    
        bool result = !IntModDiv(&result_value, &a, &b, &m);
        result      = result && (IntCompare(&result_value, 99) == 0);
    
        IntDeinit(&a);
    
        bool result = !IntPowMod(&result_value, &base, &exp, &mod);
        result      = result && (IntCompare(&result_value, 99) == 0);
    
        IntDeinit(&base);
    
        // result written, returns true, and root^2 == value (mod p).
        result = result && (IntCompare(&check, 2) == 0);
        // root must lie in [0, p).
        result = result && (IntCompare(&root, 7) < 0);
        result = result && (IntCompare(&check, 2) == 0);
        // root must lie in [0, p).
        result = result && (IntCompare(&root, 7) < 0);
        result = result && (IntCompare(&root, 0) >= 0);
        // root must actually have been overwritten away from the sentinel 99.
        // root must lie in [0, p).
        result = result && (IntCompare(&root, 7) < 0);
        result = result && (IntCompare(&root, 0) >= 0);
        // root must actually have been overwritten away from the sentinel 99.
        result = result && (IntCompare(&root, 99) != 0);
        result = result && (IntCompare(&root, 0) >= 0);
        // root must actually have been overwritten away from the sentinel 99.
        result = result && (IntCompare(&root, 99) != 0);
    
        IntDeinit(&value);
    
        bool result = !IntModSqrt(&root, &value, &mod);
        result      = result && (IntCompare(&root, 99) == 0);
    
        IntDeinit(&value);
        IntSquareMod(&check, &root, &mod);
    
        result = result && (IntCompare(&check, 2) == 0);
        result = result && (IntCompare(&root, 17) < 0);
        result = result && (IntCompare(&root, 0) >= 0);
    
        result = result && (IntCompare(&check, 2) == 0);
        result = result && (IntCompare(&root, 17) < 0);
        result = result && (IntCompare(&root, 0) >= 0);
        result = result && (IntCompare(&root, 99) != 0);
        result = result && (IntCompare(&check, 2) == 0);
        result = result && (IntCompare(&root, 17) < 0);
        result = result && (IntCompare(&root, 0) >= 0);
        result = result && (IntCompare(&root, 99) != 0);
        result = result && (IntCompare(&root, 17) < 0);
        result = result && (IntCompare(&root, 0) >= 0);
        result = result && (IntCompare(&root, 99) != 0);
    
        IntDeinit(&value);
        IntSquareMod(&check, &root, &mod);
    
        result = result && (IntCompare(&check, 4) == 0);
        result = result && (IntCompare(&root, 17) < 0);
        result = result && (IntCompare(&root, 0) >= 0);
    
        result = result && (IntCompare(&check, 4) == 0);
        result = result && (IntCompare(&root, 17) < 0);
        result = result && (IntCompare(&root, 0) >= 0);
        result = result && (IntCompare(&check, 4) == 0);
        result = result && (IntCompare(&root, 17) < 0);
        result = result && (IntCompare(&root, 0) >= 0);
    
        IntDeinit(&value);
        IntSquareMod(&check, &root, &mod);
    
        result = result && (IntCompare(&check, 3) == 0);
        result = result && (IntCompare(&root, 97) < 0);
        result = result && (IntCompare(&root, 0) >= 0);
    
        result = result && (IntCompare(&check, 3) == 0);
        result = result && (IntCompare(&root, 97) < 0);
        result = result && (IntCompare(&root, 0) >= 0);
        result = result && (IntCompare(&root, 99) != 0);
        result = result && (IntCompare(&check, 3) == 0);
        result = result && (IntCompare(&root, 97) < 0);
        result = result && (IntCompare(&root, 0) >= 0);
        result = result && (IntCompare(&root, 99) != 0);
        result = result && (IntCompare(&root, 97) < 0);
        result = result && (IntCompare(&root, 0) >= 0);
        result = result && (IntCompare(&root, 99) != 0);
    
        IntDeinit(&value);
        IntSquareMod(&check, &root, &mod);
    
        result = result && (IntCompare(&check, 2) == 0);
        result = result && (IntCompare(&root, 257) < 0);
        result = result && (IntCompare(&root, 0) >= 0);
    
        result = result && (IntCompare(&check, 2) == 0);
        result = result && (IntCompare(&root, 257) < 0);
        result = result && (IntCompare(&root, 0) >= 0);
        result = result && (IntCompare(&check, 2) == 0);
        result = result && (IntCompare(&root, 257) < 0);
        result = result && (IntCompare(&root, 0) >= 0);
    
        IntDeinit(&value);
        IntSquareMod(&check, &root, &mod);
    
        result = result && (IntCompare(&check, 10) == 0);
        result = result && (IntCompare(&root, 13) < 0);
    
        result = result && (IntCompare(&check, 10) == 0);
        result = result && (IntCompare(&root, 13) < 0);
    
        IntDeinit(&value);
    
        bool result = !IntModSqrt(&root, &value, &mod);
        result      = result && (IntCompare(&root, 99) == 0);
    
        IntDeinit(&value);
        bool result = IntModSqrt(&root, &value, &mod);
        // result overwritten to exactly 0 (not the 99 sentinel).
        result = result && (IntCompare(&root, 0) == 0);
    
        IntDeinit(&value);
    
        bool result = IntModSqrt(&root, &value, &mod);
        result      = result && (IntCompare(&root, 0) == 0);
    
        IntDeinit(&value);
    
        bool result = IntModSqrt(&root, &value, &mod);
        result      = result && (IntCompare(&root, 1) == 0);
    
        IntDeinit(&value);
    
        bool result = !IntModSqrt(&root, &value, &mod);
        result      = result && (IntCompare(&root, 99) == 0);
    
        IntDeinit(&value);
    
        bool result = !IntModSqrt(&root, &value, &mod);
        result      = result && (IntCompare(&root, 99) == 0);
    
        IntDeinit(&value);
    
        bool result = !IntModSqrt(&root, &value, &mod);
        result      = result && (IntCompare(&root, 99) == 0);
    
        IntDeinit(&value);
    
        // root^2 must equal the *reduced* value 2, not 23.
        result = result && (IntCompare(&check, 2) == 0);
        result = result && (IntCompare(&root, 7) < 0);
        // root^2 must equal the *reduced* value 2, not 23.
        result = result && (IntCompare(&check, 2) == 0);
        result = result && (IntCompare(&root, 7) < 0);
    
        IntDeinit(&value);
        bool result = IntLCM(&result_value, &a, &b);
        result      = result && IntIsZero(&result_value);
        result      = result && (IntCompare(&result_value, 0) == 0);
    
        IntDeinit(&a);
        bool ok     = IntRootRem(&root, &remainder, &value, 3);
        bool result = ok;
        result      = result && (IntCompare(&root, 0) == 0);
        result      = result && (IntCompare(&remainder, 0) == 0);
        bool result = ok;
        result      = result && (IntCompare(&root, 0) == 0);
        result      = result && (IntCompare(&remainder, 0) == 0);
    
        IntDeinit(&value);
        bool rejected = !IntPow(&power, &base, &exp);
        // Result must be left untouched on rejection.
        bool result = rejected && (IntCompare(&power, &sentinel) == 0);
    
        IntDeinit(&base);
        Int value = IntFrom(5u, &alloc.base);
    
        bool fail = (IntCompare(&value, 5u) != 0);
        fail      = fail || (IntBitLength(&value) != 3);
        Int value = IntFrom(1u, &alloc.base);
    
        bool fail = (IntCompare(&value, 1u) != 0);
        fail      = fail || (IntBitLength(&value) != 1);
        bool ok     = IntDiv(&quotient, &dividend, 0u);
        bool result = (ok == false);
        result      = result && (IntCompare(&quotient, 99) == 0);
    
        IntDeinit(&dividend);
        bool ok     = IntDiv(&quotient, &dividend, (i64)0);
        bool result = (ok == false);
        result      = result && (IntCompare(&quotient, 99) == 0);
    
        IntDeinit(&dividend);
        bool ok = IntModSqrt(&root, &value, &mod);
        IntSquareMod(&check, &root, &mod);
        bool result = ok && (IntCompare(&check, 2) == 0);
    
        IntDeinit(&value);
    
        bool ok = int_pow_mod(&result_value, &base, &exp, &mod);
        ok      = ok && (IntCompare(&result_value, 0) == 0);
    
        IntDeinit(&base);
    
        bool ok = int_pow_mod(&result_value, &base, &exp, &mod);
        ok      = ok && (IntCompare(&result_value, 0) == 0);
    
        IntDeinit(&base);
    
        bool ok = IntModInv(&inverse, &value, &modulus);
        ok      = ok && IntCompare(&inverse, 23u) == 0;
    
        IntDeinit(&value);
        bool ok = IntModSqrt(&root, &value, &modulus);
        ok      = ok && IntSquareMod(&check, &root, &modulus);
        ok      = ok && IntCompare(&check, 9u) == 0;
    
        IntDeinit(&value);
        bool ok = IntModSqrt(&root, &value, &modulus);
        ok      = ok && IntSquareMod(&check, &root, &modulus);
        ok      = ok && IntCompare(&check, 2u) == 0;
    
        IntDeinit(&value);
        // ar >= br branch: 5 - 2 = 3 (mod 7)
        Int  a1 = IntFrom(5u, alloc), b1 = IntFrom(2u, alloc);
        bool ok = IntModSub(&r, &a1, &b1, &m) && IntCompare(&r, 3u) == 0;
        // ar < br branch: 2 - 5 = -3 = 4 (mod 7)
        Int a2 = IntFrom(2u, alloc), b2 = IntFrom(5u, alloc);
        // ar < br branch: 2 - 5 = -3 = 4 (mod 7)
        Int a2 = IntFrom(2u, alloc), b2 = IntFrom(5u, alloc);
        ok = ok && IntModSub(&r, &a2, &b2, &m) && IntCompare(&r, 4u) == 0;
        // equal branch: 5 - 12 = 0 (mod 7)
        Int a3 = IntFrom(5u, alloc), b3 = IntFrom(12u, alloc);
    
        bool ok = IntNextPrime(&next, &value);
        ok      = ok && IntCompare(&next, 101u) == 0;
    
        IntDeinit(&value);
    
    bool test_int_compare_ignores_leading_zeros(void) {
        WriteFmt("Testing IntCompare leading-zero normalization\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
        Int rhs = IntFrom(11, ALLOCATOR_OF(&alloc));
    
        bool result = IntCompare(&lhs, &rhs) == 0;
        result      = result && IntEQ(&lhs, &rhs);
        Int value = IntFromBytesBE((const u8 *)0, 0, &alloc.base);
    
        bool fail = (IntCompare(&value, 0u) != 0);
    
        IntDeinit(&value);
        Int value    = IntFromBytesBE(bytes, sizeof(bytes), &alloc.base);
    
        bool fail = (IntCompare(&value, 0x010203u) != 0);
    
        IntDeinit(&value);
    
        bool fail = !parsed;
        fail      = fail || (IntCompare(&out, 5u) != 0);
    
        IntDeinit(&out);
        Int parsed = IntFromStrRadix(&hex, 16, alloc);
    
        bool ok = IntCompare(&value, &parsed) == 0;
    
        StrDeinit(&hex);
        bool result = ok;
        result      = result && (IntToU64(&root) == 12345);
        result      = result && (IntCompare(&remainder, 0) == 0);
    
        IntDeinit(&value);
    
        bool fail = !ok;                                   // must report success.
        fail      = fail || (IntCompare(&value, 7u) != 0); // value preserved.
    
        IntDeinit(&value);
        Zstr z = "9z";
        StrReadFmt(z, "{}", v);
        bool ok = (IntCompare(&v, 9) == 0);
    
        IntDeinit(&v);
        Zstr z = "5";
        StrReadFmt(z, "{}", v);
        bool ok = (IntCompare(&v, 5) == 0);
    
        IntDeinit(&v);
        Zstr z = "+8";
        StrReadFmt(z, "{}", v);
        bool ok = (IntCompare(&v, 8) == 0);
    
        IntDeinit(&v);
        Zstr z = "9_";
        StrReadFmt(z, "{}", v);
        bool ok = (IntCompare(&v, 123) == 0);
    
        IntDeinit(&v);
        Zstr z = "0xFF";
        StrReadFmt(z, "{x}", v);
        bool ok = (IntCompare(&v, 200) == 0);
    
        IntDeinit(&v);
        Zstr z = "0XFF";
        StrReadFmt(z, "{x}", v);
        bool ok = (IntCompare(&v, 200) == 0);
    
        IntDeinit(&v);
        Zstr z = "ff";
        StrReadFmt(z, "{x}", v);
        bool ok = (IntCompare(&v, 255) == 0);
    
        IntDeinit(&v);
        Zstr z = "0b1";
        StrReadFmt(z, "{b}", v);
        bool ok = (IntCompare(&v, 5) == 0);
    
        IntDeinit(&v);
        Zstr z = "0B1";
        StrReadFmt(z, "{b}", v);
        bool ok = (IntCompare(&v, 5) == 0);
    
        IntDeinit(&v);
        Zstr z = "101";
        StrReadFmt(z, "{b}", v);
        bool ok = (IntCompare(&v, 5) == 0);
    
        IntDeinit(&v);
        Zstr z = "0o7";
        StrReadFmt(z, "{o}", v);
        bool ok = (IntCompare(&v, 9) == 0);
    
        IntDeinit(&v);
        Zstr z = "0O7";
        StrReadFmt(z, "{o}", v);
        bool ok = (IntCompare(&v, 9) == 0);
    
        IntDeinit(&v);
        Zstr z = "17";
        StrReadFmt(z, "{o}", v);
        bool ok = (IntCompare(&v, 15) == 0);
    
        IntDeinit(&v);
        Zstr z = "   42";
        StrReadFmt(z, "{}", v);
        bool ok = (IntCompare(&v, 42) == 0);
    
        IntDeinit(&v);
Last updated on