Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine the sign of a 32 bit int

Using ONLY:

! ~ & ^ | + << >>

NO LOOPS

I need to determine the sign of a 32 bit integer and I need to return 1 if positive, 0 if 0 and -1 if negative.

Any ideas? I first thought about shifting over 31 bits and then looking at that sign but that obviously wont work and now I am kind of stuck.

like image 784
Peter Avatar asked Sep 07 '11 22:09

Peter


1 Answers

If conditionals (not if statements) and subtraction are allowed, the simplest & cleaner solution (IMO) is:

int sign = (v > 0) - (v < 0);

Not using subtraction (and assuming int is 32 bits):

#include <stdio.h>
#include <assert.h>
#include <limits.h>

int process(int v) {
    int is_negative = (unsigned int)v >> 31; // or sizeof(int) * CHAR_BIT - 1
    int is_zero = !v;
    int is_positive = !is_negative & !is_zero;
    int sign = (is_positive + ~is_negative) + 1;
    return sign;
}

int main() {
    assert(process(0) == 0);
    printf("passed the zero test\n");
    for (int v = INT_MIN; v < 0; v++) {
        assert(process(v) == -1);
    }
    printf("passed all negative tests\n");
    for (int v = 1; v < INT_MAX; v++) {
        assert(process(v) == +1);
    }
    printf("passed all positive tests\n");
    return 0;
}

Here's are the results:

$ gcc -o test test.c -Wall -Wextra -O3 -std=c99 && ./test && echo $#
passed zero test
passed all negative tests
passed all positive tests
0
like image 115
jweyrich Avatar answered Oct 04 '22 13:10

jweyrich