Skip to content

Instantly share code, notes, and snippets.

@n-soda
Last active July 28, 2016 03:36
Show Gist options
  • Save n-soda/93565d365d987a134a88 to your computer and use it in GitHub Desktop.
Save n-soda/93565d365d987a134a88 to your computer and use it in GitHub Desktop.
min()/max() implementation without using conditional branch instruction
/*
* max()/min() implementation without any conditional branch instruction.
* basic idea from:
* https://twitter.com/vivisuke/status/539563588332310528
* http://vivi.dyndns.org/blog/archives/306
*
* countermeasure against signed integer overflow by n-soda @ github
*
* NOTE:
* this program is NOT truly portable,
* because it is implementation-defined behavior how ">>" operator works
* against a signed integer.
*
* This code does not use conditional branch with legacy CPUs which do not
* have an instruction like x86 SETcc instruction, but for modern CPUs
* which have a SETcc equivalent, the following way which is described in
* http://graphics.stanford.edu/~seander/bithacks.html
* is better:
* maximum: return x ^ ((x ^ y) & -(x < y));
* minimum: return y ^ ((x ^ y) & -(x < y));
* and branch instructions don't have to be avoided with such legacy CPUs ;-)
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define INT_BIT (sizeof(int) * CHAR_BIT)
int int_maximum(int a, int b)
{
int diff = a - b - INT_MIN;
int a_lt_b =
(((a - b) ^ ((a ^ b) & (a ^ (a - b)))) & (a | diff | -diff))
>> (INT_BIT - 1);
return (a & ~a_lt_b) | (b & a_lt_b);
}
int int_minimum(int a, int b)
{
int diff = a - b - INT_MIN;
int a_lt_b =
(((a - b) ^ ((a ^ b) & (a ^ (a - b)))) & (a | diff | -diff))
>> (INT_BIT - 1);
return (a & a_lt_b) | (b & ~a_lt_b);
}
int main(int argc, char **argv)
{
int a, b;
if (argc != 3) {
fprintf(stderr, "Usage: %s <value-1> <value-2>\n", argv[0]);
return 1;
}
a = atoi(argv[1]);
b = atoi(argv[2]);
printf("maximum(%d, %d) = %d\n", a, b, int_maximum(a, b));
printf("minimum(%d, %d) = %d\n", a, b, int_minimum(a, b));
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment