Express bitwise negation (`NOT`, bitwise complement) using other bitwise operations? - bit-manipulation

I am writing an algorithm in a limited language where the bitwise operators at my disposal are
AND: &
OR: |
XOR: ^
SRL: << (shift left)
SLL: >> (shift right)
I realized I need to be able to take the bitwise complement of an integer, commonly denoted ~x in other languages.
Could I somehow express ~x, using only the {&, |, ^, <<, >>} operators?
I would try to just implement this operator in the language’s compiler, but it seems like a very challenging task. I would much rather do some dirty hack to express NOT x without ~.

Related

In C (also C++), how '&' operator works as both address operator and bitwise operator ? As operator overloading is not supported by C

The operator '&' can be used in both of following way int a; scanf("%d",&a);
and printf("%d",1&2).
But different behaviour (for first as address operator and second time as bit-wise operator).
I know operator overloading is not there in C. Then how it works ?. Also highlight for c++.
I know operator overloading is not there in C.
This is incorrect. a + b performs integer addition if a and b are integers, floating-point addition of a and b are floating-point numbers, and pointer arithmetic if a or b is a pointer.
C has operator overloading built into the language. It does not support custom operator overloading defined by the program.
In the case of & being an operator for taking an address and for performing a bitwise AND, the distinction is made by the language grammar. The & for taking an address can appear only applied to a cast-expression in the grammar. The & for bitwise AND can appear only after an AND-expression and before an equality-expression. These “tokens” (cast-expression, AND-expression, and equality-expression) may be unfamiliar to you, but they are formally defined in the grammar for the C language, and, as the compiler is parsing source code, it recognizes the structure of expressions and matches the source code to the tokens of the grammar. This is also true for C++ except for a minor technical difference: In C++, one of the tokens is and-expression instead of AND-expression.
The definition of the grammar is such that recognition of these tokens always uniquely distinguishes how the & operator is being used.
In "C" language, operators have different meaning when they are used as prefix to expression, suffix to expression or "infix" (between two expressions).
Consider '*', which performs multiplication as 'infix' operator, and pointer indirection when used as a prefix. Similarily, the '-' operator, which performs subtraction as 'infix' operator, and negation when used as a prefix.
Basically, it's not about overriding, it if the operator appears between two expressions, or as a prefix to a single expression.
In the same way, The "C" compiler knows if the '&' is bit-wise and, or address-of, based on it's position is the expression: If it is between two expressions, it's the AND, if it is before an expression, it is 'address-of'.
See https://en.wikipedia.org/wiki/Infix_notation about infix.
C does not support operator overloading (beyond what it built into the language).
As you can see in this Wikipedia Operators in C
The Address-of ("address of a") "&a" is defined as R* K::operator &();
whereas
The Bitwise AND "a & b" is defined as R K::operator &(S b);
So basically the "&" operator has different meaning when used as a unary operator and as a binary operator operator. The same goes for various other operators like, "*" , "-", etc.
It has simple different meanings when applied to the lvalue (it the unary operator in this case) or when it is used in the math expression with two operands.
"The operator & can be used in both of following way int a; scanf("%d",&a); and printf("%d",1&2)."
Note that in the case of C++ you forgot another important third use. The & operator can also be used to declare references.
int x = 24;
int& r_x = x;
the language divides operators based on its operands first. In one category itself overloading can be in-built. Your example is about the first division. Address-of is a unary operator and bitwise-AND is a binary operator. when you write operator function in c++ you will see the difference of these two categories.
Operator overloading is inbuilt to languages. example simple arithmetic addition operator. it can work with simple one-byte integer data as well as float (significant & exponent). Basically it is there with maths. so while making C language, they just translated those into functionality. In C specification, you cannot find overloading as a keyword for this behavior. According to them, after formula expression, anything has to be expressed as different functions. Each function should be named based on the functionality that it offers. When C++ introduced an opportunity to create new types, operators with its basic n-nary form allowed to operate with new types. In a nutshell, C's philosophy was different.

Simplifying a bitwise operation

I have the following bitwise expression and was wondering if it could be simplified or if there is a general way of interpreting the output.
(x & y) | (~x & ~y)
The only "simpler" version is ~(x^y) (where ^ is the XOR operator).
However, It's not going to make a significant difference computationally, and is harder to read for most people (XOR is not as natural as AND and OR). There's not a simpler version using just AND and OR operators, so I would suggest you just leave it as-is.
if there is a general way of interpreting the output.
"Either both are true or both are false" is a natural interpretation.

How does the bang operator (!) work against bits?

I've been asked to compute !x without using !.
Examples:
bang(3) = 0
bang(0) = 1
The legal operations: ~, $, |, ^, +, <<, >>
I don't understand what a bang does? I thought it was a factorial.
If in C, your "!" is a boolean inverse of its argument. So, !0 yields 1 and 1(anything else) yields 0. The "~" is the bitwise version of it, essentially flipping each bit in the (following) number - much easier to understand if you constrain yourself to unsigned numbers.
!x can be emulated with things like (x?1:0) - which isn't in your list - and the && and || operators - which also aren't in your list. "$" isn't an operator in C, so I'm a bit puzzled by that one - what language are you in? You might have some luck using the | and looping through all the bits to figure out if any are set, after that point using the bitwise operators on just your resulting 1 bit make it pretty easy to emulate "!".
I could just lay it out, but if you're taking a class, the struggle is where most of the gain is for this particular problem.
! is the logical negation operator. Your favorite search engine will tell you more.

What happen first, casting or shifting bits [C++]

What's happening first here in C++, shift or casting?
(dword)header[2]<<8
From here Operator precedence you can see that bitwise shift has lower precedence than type cast. So that is equivalent to:
((dword) (header[2])) << 8
Always use parentheses for things that are not clear, even if you check that it is actually ok, because it improves code readability. (you might not want to enclose the subscript like I did to emphasis all the precedences here, but use the other parenthesis).

C++ warning: suggest parentheses around arithmetic in operand of |

I have a code like
A = B|C|D|E;
Throwing the warning "suggest parentheses around arithmetic in operand of |"
Expecting that expression needs high priority paranthesis for operators, tried the following ways:
A=(B|C)|(D|E);
one more as :
A=(((B|C)|D)|E);
Still the same warning persists.
Please help me in resolving this.
Thanks,
Sujatha
B, C,D are enums and E is an integer.
You have some arithmetic operator in your expression that isn't really simply B, or that isn't really simply C, etc. The compiler is suggesting that you parenthesize whichever expression so that readers will see that you wrote what you meant. If you don't parenthesize, everyone has to remember exactly what the priorities are, and they have to figure out if you remembered when you wrote it.
Try this: (B)|(C)|(D)|(E).
This is a weird warning. You only really need to pay attention to precedence when you're using different operators and those operators have different precedences. For instance, in arithmetic multiplication has higher precedence than addition.
But in this case you're using only one operator multiple times. Bitwise or is associative and commutative ((A | B) | C == A | (B | C) and A | B == B | A) so there's really no reason for the warning.