Is it possible to implement bitwise operators using integer arithmetic?

后端 未结 6 1316
青春惊慌失措
青春惊慌失措 2021-01-29 22:05

I am facing a rather peculiar problem. I am working on a compiler for an architecture that doesn\'t support bitwise operations. However, it handles signed 16-bit integer arithme

6条回答
  •  广开言路
    2021-01-29 22:33

    An incomplete answer on an old question, here concentrating on AND, OR, XOR. Once a solution is found for one of these bitwise operations, the other two can be derived. There are several ways, one is shown in the following test program (compiled on gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)).

    In December 2018 I discovered an error in the solution. The XOR commented below only works because intermediate results in a+b-2*AND(a,b) are promoted to int, which is larger than 16 bits for all modern compilers.

    #include 
    #include 
    #include 
    
    //#define XOR(a,b) (a + b - 2*AND(a,b)) // Error. Intermediate overflow
    #define XOR(a,b) (a - AND(a,b) +  b - AND(a,b) )
    #define IOR(a,b) XOR(XOR(a,b),AND(a,b)) // Credit to Jan Gray, Gray Research LLC, for IOR
    static const uint16_t andlookup[256] = {
    #define C4(a,b) ((a)&(b)), ((a)&(b+1)), ((a)&(b+2)), ((a)&(b+3))
    #define L(a) C4(a,0), C4(a,4), C4(a,8), C4(a,12)
    #define L4(a) L(a), L(a+1), L(a+2), L(a+3)
        L4(0), L4(4), L4(8), L4(12)
    #undef C4
    #undef L
    #undef L4
    };
    
    uint16_t AND(uint16_t a, uint16_t b) {
        uint16_t r=0, i;
    
        for ( i = 0; i < 16; i += 4 ) {
                r = r/16 + andlookup[(a%16)*16+(b%16)]*4096;
                a /= 16;
                b /= 16;
        }
        return r;
    }
    
    int main( void ) {
        uint16_t a = 0, b = 0;
    
        do {
                do {
                        if ( AND(a,b) != (a&b) ) return printf( "AND error\n" );
                        if ( IOR(a,b) != (a|b) ) return printf( "IOR error\n" );
                        if ( XOR(a,b) != (a^b) ) return printf( "XOR error\n" );
                } while ( ++b != 0 );
                if ( (a & 0xff) == 0 )
                        fprintf( stderr, "." );
        } while ( ++a != 0 );
        return 0;
    }
    

提交回复
热议问题