This one has no branches, and doesn't suffer from overflow or underflow:

return (a > b) - (a < b);

With gcc -O2 -S, this compiles down to the following six instructions:

xorl    %eax, %eax
cmpl    %esi, %edi
setl    %dl
setg    %al
movzbl  %dl, %edx
subl    %edx, %eax

Here's some code to benchmark various compare implementations:

#include <stdio.h>
#include <stdlib.h>

#define COUNT 1024
#define LOOPS 500
#define COMPARE compare2
#define USE_RAND 1

int arr[COUNT];

int compare1 (int a, int b)
{
    if (a < b) return -1;
    if (a > b) return 1;
    return 0;
}

int compare2 (int a, int b)
{
    return (a > b) - (a < b);
}

int compare3 (int a, int b)
{
    return (a < b) ? -1 : (a > b);
}

int compare4 (int a, int b)
{
    __asm__ __volatile__ (
        "sub %1, %0 \n\t"
        "jno 1f \n\t"
        "cmc \n\t"
        "rcr %0 \n\t"
        "1: "
    : "+r"(a)
    : "r"(b)
    : "cc");
    return a;
}

int main ()
{
    for (int i = 0; i < COUNT; i++) {
#if USE_RAND
        arr[i] = rand();
#else
        for (int b = 0; b < sizeof(arr[i]); b++) {
            *((unsigned char *)&arr[i] + b) = rand();
        }
#endif
    }

    int sum = 0;

    for (int l = 0; l < LOOPS; l++) {
        for (int i = 0; i < COUNT; i++) {
            for (int j = 0; j < COUNT; j++) {
                sum += COMPARE(arr[i], arr[j]);
            }
        }
    }

    printf("%d=0\n", sum);

    return 0;
}

The results on my 64-bit system, compiled with gcc -std=c99 -O2, for positive integers (USE_RAND=1):

compare1: 0m1.118s
compare2: 0m0.756s
compare3: 0m1.101s
compare4: 0m0.561s

Out of C-only solutions, the one I suggested was the fastest. user315052's solution was slower despite compiling to only 5 instructions. The slowdown is likely because, despite having one less instruction, there is a conditional instruction (cmovge).

Overall, FredOverflow's 4-instruction assembly implementation was the fastest when used with positive integers. However, this code only benchmarked the integer range RAND_MAX, so the 4-instuction test is biased, because it handles overflows separately, and these don't occur in the test; the speed may be due to successful branch prediction.

With a full range of integers (USE_RAND=0), the 4-instruction solution is in fact very slow (others are the same):

compare4: 0m1.897s
Answer from Ambroz Bizjak on Stack Overflow
Top answer
1 of 7
97

This one has no branches, and doesn't suffer from overflow or underflow:

return (a > b) - (a < b);

With gcc -O2 -S, this compiles down to the following six instructions:

xorl    %eax, %eax
cmpl    %esi, %edi
setl    %dl
setg    %al
movzbl  %dl, %edx
subl    %edx, %eax

Here's some code to benchmark various compare implementations:

#include <stdio.h>
#include <stdlib.h>

#define COUNT 1024
#define LOOPS 500
#define COMPARE compare2
#define USE_RAND 1

int arr[COUNT];

int compare1 (int a, int b)
{
    if (a < b) return -1;
    if (a > b) return 1;
    return 0;
}

int compare2 (int a, int b)
{
    return (a > b) - (a < b);
}

int compare3 (int a, int b)
{
    return (a < b) ? -1 : (a > b);
}

int compare4 (int a, int b)
{
    __asm__ __volatile__ (
        "sub %1, %0 \n\t"
        "jno 1f \n\t"
        "cmc \n\t"
        "rcr %0 \n\t"
        "1: "
    : "+r"(a)
    : "r"(b)
    : "cc");
    return a;
}

int main ()
{
    for (int i = 0; i < COUNT; i++) {
#if USE_RAND
        arr[i] = rand();
#else
        for (int b = 0; b < sizeof(arr[i]); b++) {
            *((unsigned char *)&arr[i] + b) = rand();
        }
#endif
    }

    int sum = 0;

    for (int l = 0; l < LOOPS; l++) {
        for (int i = 0; i < COUNT; i++) {
            for (int j = 0; j < COUNT; j++) {
                sum += COMPARE(arr[i], arr[j]);
            }
        }
    }

    printf("%d=0\n", sum);

    return 0;
}

The results on my 64-bit system, compiled with gcc -std=c99 -O2, for positive integers (USE_RAND=1):

compare1: 0m1.118s
compare2: 0m0.756s
compare3: 0m1.101s
compare4: 0m0.561s

Out of C-only solutions, the one I suggested was the fastest. user315052's solution was slower despite compiling to only 5 instructions. The slowdown is likely because, despite having one less instruction, there is a conditional instruction (cmovge).

Overall, FredOverflow's 4-instruction assembly implementation was the fastest when used with positive integers. However, this code only benchmarked the integer range RAND_MAX, so the 4-instuction test is biased, because it handles overflows separately, and these don't occur in the test; the speed may be due to successful branch prediction.

With a full range of integers (USE_RAND=0), the 4-instruction solution is in fact very slow (others are the same):

compare4: 0m1.897s
2 of 7
57

The following has always proven to be fairly efficient for me:

return (a < b) ? -1 : (a > b);

With gcc -O2 -S, this compiles down to the following five instructions:

xorl    %edx, %edx
cmpl    %esi, %edi
movl    $-1, %eax
setg    %dl
cmovge  %edx, %eax

As a follow-up to Ambroz Bizjak's excellent companion answer, I was not convinced that his program tested the same assembly code what was posted above. And, when I was studying the compiler output more closely, I noticed that the compiler was not generating the same instructions as was posted in either of our answers. So, I took his test program, hand modified the assembly output to match what we posted, and compared the resulting times. It seems the two versions compare roughly identically.

./opt_cmp_branchless: 0m1.070s
./opt_cmp_branch:     0m1.037s

I am posting the assembly of each program in full so that others may attempt the same experiment, and confirm or contradict my observation.

The following is the version with the cmovge instruction ((a < b) ? -1 : (a > b)):

        .file   "cmp.c"
        .text
        .section        .rodata.str1.1,"aMS",@progbits,1
.LC0:
        .string "%d=0\n"
        .text
        .p2align 4,,15
.globl main
        .type   main, @function
main:
.LFB20:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        pushq   %rbx
        .cfi_def_cfa_offset 24
        .cfi_offset 3, -24
        movl    $arr.2789, %ebx
        subq    $8, %rsp
        .cfi_def_cfa_offset 32
.L9:
        leaq    4(%rbx), %rbp
.L10:
        call    rand
        movb    %al, (%rbx)
        addq    $1, %rbx
        cmpq    %rbx, %rbp
        jne     .L10
        cmpq    $arr.2789+4096, %rbp
        jne     .L9
        xorl    %r8d, %r8d
        xorl    %esi, %esi
        orl     $-1, %edi
.L12:
        xorl    %ebp, %ebp
        .p2align 4,,10
        .p2align 3
.L18:
        movl    arr.2789(%rbp), %ecx
        xorl    %eax, %eax
        .p2align 4,,10
        .p2align 3
.L15:
        movl    arr.2789(%rax), %edx
        xorl    %ebx, %ebx
        cmpl    %ecx, %edx
        movl    $-1, %edx
        setg    %bl
        cmovge  %ebx, %edx
        addq    $4, %rax
        addl    %edx, %esi
        cmpq    $4096, %rax
        jne     .L15
        addq    $4, %rbp
        cmpq    $4096, %rbp
        jne     .L18
        addl    $1, %r8d
        cmpl    $500, %r8d
        jne     .L12
        movl    $.LC0, %edi
        xorl    %eax, %eax
        call    printf
        addq    $8, %rsp
        .cfi_def_cfa_offset 24
        xorl    %eax, %eax
        popq    %rbx
        .cfi_def_cfa_offset 16
        popq    %rbp
        .cfi_def_cfa_offset 8
        ret
        .cfi_endproc
.LFE20:
        .size   main, .-main
        .local  arr.2789
        .comm   arr.2789,4096,32
        .section        .note.GNU-stack,"",@progbits

The version below uses the branchless method ((a > b) - (a < b)):

        .file   "cmp.c"
        .text
        .section        .rodata.str1.1,"aMS",@progbits,1
.LC0:
        .string "%d=0\n"
        .text
        .p2align 4,,15
.globl main
        .type   main, @function
main:
.LFB20:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        pushq   %rbx
        .cfi_def_cfa_offset 24
        .cfi_offset 3, -24
        movl    $arr.2789, %ebx
        subq    $8, %rsp
        .cfi_def_cfa_offset 32
.L9:
        leaq    4(%rbx), %rbp
.L10:
        call    rand
        movb    %al, (%rbx)
        addq    $1, %rbx
        cmpq    %rbx, %rbp
        jne     .L10
        cmpq    $arr.2789+4096, %rbp
        jne     .L9
        xorl    %r8d, %r8d
        xorl    %esi, %esi
.L19:
        movl    %ebp, %ebx
        xorl    %edi, %edi
        .p2align 4,,10
        .p2align 3
.L24:
        movl    %ebp, %ecx
        xorl    %eax, %eax
        jmp     .L22
        .p2align 4,,10
        .p2align 3
.L20:
        movl    arr.2789(%rax), %ecx
.L22:
        xorl    %edx, %edx
        cmpl    %ebx, %ecx
        setg    %cl
        setl    %dl
        movzbl  %cl, %ecx
        subl    %ecx, %edx
        addl    %edx, %esi
        addq    $4, %rax
        cmpq    $4096, %rax
        jne     .L20
        addq    $4, %rdi
        cmpq    $4096, %rdi
        je      .L21
        movl    arr.2789(%rdi), %ebx
        jmp     .L24
.L21:
        addl    $1, %r8d
        cmpl    $500, %r8d
        jne     .L19
        movl    $.LC0, %edi
        xorl    %eax, %eax
        call    printf
        addq    $8, %rsp
        .cfi_def_cfa_offset 24
        xorl    %eax, %eax
        popq    %rbx
        .cfi_def_cfa_offset 16
        popq    %rbp
        .cfi_def_cfa_offset 8
        ret
        .cfi_endproc
.LFE20:
        .size   main, .-main
        .local  arr.2789
        .comm   arr.2789,4096,32
        .section        .note.GNU-stack,"",@progbits
🌐
TutorialsPoint
tutorialspoint.com › learn_c_by_examples › compare_two_integers_in_c.htm
Compare two integers in C
#include <stdio.h> int main() { int a, b; a = 11; b = 99; // to take values from user input uncomment the below lines − // printf("Enter value for A :"); // scanf("%d", &a); // printf("Enter value for B :"); // scanf("%d", &b); if(a > b) printf("a is greater than b"); else printf("a is not greater than b"); return 0; }
🌐
Quora
quora.com › How-do-I-compare-an-integer-with-a-Character-variable-in-C
How to compare an integer with a Character variable in C - Quora
Answer (1 of 6): Your code is a bit hazy. What you have written seems erroneous. [code ]char hi[][/code] → character array or string if that is what you prefer to call it. [code ]int b [/code]→ a simple integer, signed and not an array. Let’s say you mean [code ]char hi=’a’;[/code] ...
🌐
Dot Net Perls
dotnetperls.com › compareto
C# - CompareTo Method - Dot Net Perls
using System; class Program { static void Main() { const int a = ... 5; int ab = a.CompareTo(b); int ba = b.CompareTo(a); int ca = c.CompareTo(a); Console.WriteLine(ab); Console.WriteLine(ba); Console.WriteLine(ca); } }
🌐
Reddit
reddit.com › r/c_programming › how to interpret an *(int*) in integer comparison function
r/C_Programming on Reddit: How to interpret an *(int*) in integer comparison function
June 19, 2022 -

In the following function:

int cmp_int(const void *va, const void *vb)
{
    int a = *(int*)va;
    int b = *(int*)vb;
    return a < b ? -1 : a > b ? +1 : 0;
}

I'm a bit confused as to what int a = *(int*)va actually is doing. I'm assuming that this is treating va as an integer when copying to a, given it's initialized as void type?

Top answer
1 of 5
11
Casting a void pointer to an int pointer and then dereferencing it to get the int being pointed to.
2 of 5
5
It might help if you broke it down a bit. int cmp_int(const void *va, const void *vb) { const int *ia = (const int*)va; const int *ib = (const int*)vb; int a = *ia; int b = *ib; return a < b ? -1 : a > b ? +1 : 0; } You'll see functions like this a lot in stuff like sorting algorithms. Since C doesn't have generics you can't do a template function that calls a comparison function with pointers to the correct type. Here we're just taking the safety rails off and using void pointers. This is the "don't screw it up and it'll all work fine" approach. BTW, that last line is a big no-no in my opinion. Do not chain the ternary operator. In fact, don't even use the ternary operator unless an if statement really won't fit there, such as in the iteration expression of a for loop. That line is just convoluted for no reason, an if statement will produce the same code and remain readable. That's just personal preference, but in my experience chaining the ternary operator will cause you to mis-read that at some point, or even gloss right over that it's chained and that there are 2 branches there. I've never once been glad that I saved lines on something like that, but many times cursed myself for using convoluted expressions. You can also frontload all the casting by casting the function pointer, not the parameters inside the function. This does the same thing in the end, but makes the function a bit more readable. It does, however, hide any errors or warnings you'll get if the function signature is incorrect. int cmp_int(const int* a, const int* b) { if(*a < *b) return -1; else if(*a > *b) return 1; else return 0; } qsort(arr, 100, sizeof(int), (int(*)(const void*, const void*))cmp_int);
🌐
Oracle
docs.oracle.com › javase › 8 › docs › api › java › lang › Comparable.html
Comparable (Java Platform SE 8 )
October 20, 2025 - {(x, y) such that x.compareTo(y) == 0}. It follows immediately from the contract for compareTo that the quotient is an equivalence relation on C, and that the natural ordering is a total order on C. When we say that a class's natural ordering is consistent with equals, we mean that the quotient for the natural ordering is the equivalence relation defined by the class's equals(Object) method: ... This interface is a member of the Java Collections Framework.
Find elsewhere
🌐
GeeksforGeeks
geeksforgeeks.org › c# › int32-compareto-method-in-c-sharp-with-examples
Int32.CompareTo Method in C# with Examples - GeeksforGeeks
July 11, 2025 - // C# program to demonstrate the // Int32.CompareTo(Int32) Method using System; class GFG { // Main Method public static void Main() { // Declaring and initializing value1 int value1 = 10; // Declaring and initializing value2 int value2 = 20; // using CompareTo() method int status = value1.CompareTo(value2); // checking the status if (status > 0) Console.WriteLine("{0} is greater than {1}", value1, value2); else if (status < 0) Console.WriteLine("{0} is less than {1}", value1, value2); else Console.WriteLine("{0} is equal to {1}", value1, value2); } }
🌐
Cppreference
en.cppreference.com › w › c › language › operator_comparison.html
Comparison operators - cppreference.com
Care must be taken when comparing floating-point values for equality, because the results of many operations cannot be represented exactly and must be rounded. In practice, floating-point numbers are usually compared allowing for the difference of one or more units of the last place. ... #include <assert.h> int main(void) { assert(2+2 == 4.0); // int converts to double, two 4.0's compare equal int n[2][3] = {1,2,3,4,5,6}; int* p1 = &n[0][2]; // last element in the first row int* p2 = &n[1][0]; // start of second row assert(p1+1 == p2); // compare equal double d = 0.0/0.0; // NaN assert( d != d ); // NaN does not equal itself float f = 0.1; // f = 0.100000001490116119384765625 double g = 0.1; // g = 0.1000000000000000055511151231257827021181583404541015625 assert(f != g); // different values }
🌐
Reddit
reddit.com › r/learnprogramming › comparing integers (c)
r/learnprogramming on Reddit: Comparing integers (C)
March 24, 2022 -

In C,

What is the easiest way to see which integer is the biggest one? So if I have 4 integers,

int i[4];

i[0] = 4;

i[1] = 6;

i[2] = 0;

i[3] = 8;

i[3] is the greatest one, but what is the easiest way of finding that out. You can make if statements checking if each variable is bigger than the other but that would be a lot of if statements and would be hard to read. Is there an easier way? Or a function I could use?

Thank you.

🌐
Cprogramming
cboard.cprogramming.com › c-programming › 180410-compare-integers-array.html
Compare integers in an array
int main(void) { int array[5] = {2, 4, 6, 1, 5}; int j, k; for (j =0; j < 5; j++) for (k = 0; k < 5; k++) { char compare; if (array[j] < array[k]) compare = '<'; else if (array[j] > array[k]) compare = '>'; else compare = '='; printf(array[%d] %c array[%d]\n", j, compare, k); } }
🌐
Quora
quora.com › What-is-the-most-efficient-way-to-compare-two-integers-for-equality-in-Java-or-C
What is the most efficient way to compare two integers for equality in Java or C++? - Quora
Answer: Letting the compiler optimize it for you. Let’s assume for a second that writing this: [code]bool test = 3 & 4; [/code]was producing more efficient instructions than this: [code]bool test = 3 == 4; [/code]You may know it and take advantage of it when you remember to do so. The compile...
🌐
GeeksforGeeks
geeksforgeeks.org › c# › int16-compareto-method-in-c-sharp
Int16.CompareTo() Method in C# - GeeksforGeeks
July 11, 2025 - This method is used to compare the current instance to a specified 16-bit signed integer and returns an integer which shows whether the value of the current instance is less than, equal to, or greater than the value of the specified 16-bit signed ...
🌐
W3Schools
w3schools.com › c › c_operators_comparison.php
C Comparison Operators
The return value of a comparison is either 1 or 0, which means true (1) or false (0). These values are known as Boolean values, and you will learn more about them in the Booleans and If..Else chapter. In the following example, we use the greater than operator (>) to find out if 5 is greater than 3: int x = 5; int y = 3; printf("%d", x > y); // returns 1 (true) because 5 is greater than 3 Try it Yourself »
🌐
Microsoft Learn
learn.microsoft.com › en-us › dotnet › api › system.int32.compareto
Int32.CompareTo Method (System) | Microsoft Learn
public: virtual int CompareTo(System::Object ^ value); ... An object to compare, or null. ... A signed number indicating the relative values of this instance and value. ... Any instance of Int32, regardless of its value, is considered greater ...
🌐
Quora
quora.com › How-do-you-compare-between-a-pointer-and-an-integer-when-compiling-C-development
How to compare between a pointer and an integer when compiling (C, development) - Quora
But seriously, you should never, ever, ever, ever, ever compare a pointer with an integer. They are not the same thing. In languages like C and C++, the size of a pointer and the size of an int are neve...
🌐
Cplusplus
cplusplus.com › reference › string › string › compare
Cplusplus
Compares the value of the string object (or a substring) to the sequence of characters specified by its arguments. The compared string is the value of the string object or -if the signature used has a pos and a len parameters- the substring that begins at its character in position pos and spans ...