1

Are there unary bitwise reduction operators in C like there are in Verilog?

Like in Verilog we have:

$display (" &  4'b1001 = %b", (&  4'b1001));

and the output of the function above is:

  &  4'b1001 = 0

I couldn't find a similar operator for C. Is there such an operation in C language?

4
  • What does the operator do? Can you describe it in detail or show more examples? Commented Feb 20, 2024 at 16:08
  • nandland.com/reduction-operators ... in standard C you have to write a loop and shift your bits to do such a reduction to a one bit result Commented Feb 20, 2024 at 16:10
  • 2
    For & and 4 bits this is just x==15. | would be x!=0. No general equivalent though. Commented Feb 20, 2024 at 16:17
  • The syntax differs but yes... you can do the same in C Commented Feb 20, 2024 at 16:42

2 Answers 2

4

In C, assuming unsigned or two’s complement, !~x or ~x == 0 serves as a bitwise AND; it is 1 if and only if each bit of x is 1.

!!x or x != 0 serves as a bitwise OR; it is 1 if any bit of x is 1.

The negations, not properly called NAND or NOR since they do not apply a NAND or NOR in a bitwise fashion but rather apply a NOT to the bitwise AND or OR, are simply !!~x or ~x != 0 and !x or x == 0.

There is no bitwise XOR in the operations specified by the C standard. GCC has __builtin_parity which can provide this.

The above apply to the full width of x. Narrower widths can be implemented by setting the extra bits to identity elements (1 for AND, 0 for OR and XOR).

Sign up to request clarification or add additional context in comments.

4 Comments

I tried running the code using the operands you mentioned and it didn't work. I used the following code: // Online C compiler to run C program online #include <stdio.h> int main() { // int x = 0; // unsigned x = 1; unsigned short x = 0; // char x = 0; if (~x == 0) { printf("all bits of x are 0 \n\n"); } else { printf("all bits of x are NOT 0 \n\n"); } if (!~x) { printf("all bits of x are 0"); } else { printf("all bits of x are NOT 0"); } return 0; }
@AZ123: You requested bitwise reduction operators. That is what I provided. ~x == 0 evaluates to 1 if the bitwise AND of the bits in x is 1, which is the case if all bits of x are 1, and to 0 otherwise, which is the case if any bit of x is 0. Your code appears to expect ~x == 0 to evaluate to true if “all bits of x are 0”. That is a different function, not a bitwise AND. It is, in fact, the negation of a bitwise OR, which is, as I wrote !x or x == 0. Also note that if you use less than a full width unsigned, you should set the remaining bits to an identity element., as I wrote.
I tried taking care of all the bits but still both values of x give the same answer as below. #include <stdio.h> int main() { unsigned short x = 0; x = x & 0xffff; if (~x == 0) { printf("all bits of x are NOT 0 \n\n"); } else { printf("all bits of x are 0 \n\n"); } x = 65535; x = x & 0xffff; if (~x == 0) { printf("all bits of x are NOT 0 \n\n"); } else { printf("all bits of x are 0 \n\n"); } } //output // all bits of x are 0 // all bits of x are 0
@AZ123: First, fix your messages. In the if clause, “all bits of x are NOT 0” appears to mean “all bits of x are 1”. That is not the complement of the sentence you have in the else clause, “all bits of x are 0.” The complement of “all bits of x are 0” is “not all bits of x are 0.” Second, use the right code. If you want true for “all bits of x are 0”, use the code for bitwise AND. For “not all bits of x are 0”, use the code for the negation of bitwise AND. For “all bits of x are 1”, use the code for bitwise OR. For “not all bits of x are 1”, use the code for negation of bitwise OR.
1

There are no dedicated operators for this, however in most cases you can achieve the same result using bitwise operators and casting the result to a bool, which effectively is a single bit. For example:

  • AND: bitwise invert, convert to bool, negate:
    bool and_reduction_4_bits(int n) {
        return !(~n & 0b1111); // C23 adds binary literals
    }
    
  • OR: just convert to bool
    bool or_reduction(int n) {
        return n; // works for any number of bits
    }
    

The tricky one is XOR reduction. This could be done if you have a way to count the number of bits set, and then just check if that number is odd. Some compilers provide a builtin popcount() function to do that. If not, you can create your own function using bit twiddling hacks.

  • XOR: count bits, check if odd
    bool xor_reduction(int n) {
        return popcount(n) & 1;
    }
    

3 Comments

Not the best hack for that, the xor reduction is also called parity.
@teapot418, You seem to be claiming that (((n * 0x0101010101010101ULL) & 0x8040201008040201ULL) % 0x1FF) & 1 is better than popcount(n) & 1? Why? It uses more operations, it's far more opaque, and it only works on bytes.
@ikegami I am reacting to "if you don't have popcount, you can use this hack (link to popcount hacks)" which has an even worse monstrosity as one of the options. And pointing out that instead of using the bit twiddling hack for popcount, you can go to the section about parity instead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.