<p>In C, the relative precedence of bitwise operators is as follows, from high to low precedence:</p>
<pre><code>~       bitwise NOT
&lt;&lt; &gt;&gt;   bitwise left shift and right shift
&amp;       bitwise AND
^       bitwise XOR
|       bitwise OR
</code></pre>
<p>It makes sense that <code>~</code> have a higher precedence than <code>&amp;</code> which itself have a higher precedence than <code>|</code>, by analogy to the precedence of logical operators.</p>
<p>What I'm wondering is if the precedence of bitwise XOR <code>^</code> is right or if maybe it should be on the same level as bitwise OR <code>|</code>?</p>
<p>Additionally, I'm wondering what is the rationale for having the precedence of the bitwise shift operators <code>&lt;&lt;</code> and <code>&gt;&gt;</code> where it is and if it corresponds to their regular use cases, specifically in relation with bitwise AND <code>&amp;</code>? If it is in an awkward position, where should it be ideally?</p>

<syntax><operators><precedence><bitwise-operators>
What should be the precedence of the bitwise operators relative to each others?
CC BY-SA 4.0
2024-03-25T17:33:39.453Z
Are you designing a new language that uses these same operators?
Eric Lippert
CC BY-SA 4.0
2024-03-25T17:44:26.457Z
@EricLippert I'm trying to design a language that have **these** operators period, yes. I don't understand your comment, having these operators is the norm in every imperative and scripting languages.
WhiteMist
CC BY-SA 4.0
2024-03-25T20:07:18.480Z
These are common choices; I would encourage you to look at more languages if you genuinely think these are the only choices, or the best choices. My question was intended to clarify whether you were asking about historical defects in the design of C that we're now aware of with the benefit of hindsight, or if you were asking to inform the design of a new language.
Eric Lippert
CC BY-SA 4.0
2024-03-25T20:13:22.347Z
There's also the possibility of _incomparable_, non-transitive, precedences, [as in Fortress](https://softwareengineering.stackexchange.com/a/391296/271624) and some other language I don't remember ATM. (See also ["Fortress Features and Lessons Learned"](https://labs.oracle.com/pls/apex/f?p=94065:10:2849938467431:5316).)
Pablo H
CC BY-SA 4.0
2024-03-25T22:30:05.310Z
As currently set out this question seems to be asking just for opinions, which isn't a kind of question that works well here, but if it were seeking *evidence* specifically (e.g. from empirical studies of bugs or defect rates, user studies on comprehensibility, languages being forced to change precedence rules) then it would make for a strong question. Alternatively, it could focus on the historical elements that are already there ("what is the rationale for...") and would then be a [tag:history] question about this traditional set of operations. It can't really be both, but which do you want?
Michael Homer
CC BY-SA 4.0
2024-03-26T14:09:25.750Z
To me it is logical that the bitwise shift operators have high precedence as they are sort of 'equivalent/most similar' to multiplication/exponentiation. And bitwise OR is the most similar to addition and has the lowest.
CPlus
<h1>If you want to minimize the need for parentheses</h1>
<p>Let's typical use case of bitshift/masking operations.</p>
<h2>Bit arrays</h2>
<p>Suppose that you have a bit array class, allowing an integer (or array of integers) to be treated as an array of bits.  It provides the operations:</p>
<ul>
<li>get <code>bitarray[i]</code> → <code>if ((backing_int &amp; (1 &lt;&lt; i)) != 0)</code></li>
<li>set <code>bitarrary[i] = value</code> → <code>backing_int = (backing_int &amp; ~(1 &lt;&lt; i)) | (value &lt;&lt; i)</code></li>
</ul>
<p>To make these work without parentheses, you would need the precedence order:</p>
<ol>
<li>Shifts (<code>&lt;&lt;</code> and <code>&gt;&gt;</code>)</li>
<li>NOT (<code>~</code>)</li>
<li>AND (<code>&amp;</code>)</li>
<li>OR (<code>|</code>)</li>
<li>Relationals (<code>==</code>, <code>!=</code>, etc.)</li>
</ol>
<p>Note that I only used left shift (<code>&lt;&lt;</code>), not right shift (<code>&gt;&gt;</code>), but since these are parallel and inverse operators, similar to <code>+</code> and <code>-</code>, it would be weird to not have them at the same precedence level.</p>
<p>Also, I didn't include XOR (<code>^</code>) in my example.  If you think of XOR as being a one-bit addition (with the carry bit ignored), then it makes sense to place it below AND (which is a one-bit multiplication).  If you think of XOR as being a Boolean <code>!=</code> operator, it makes sense to treat them at the same level as relationals — <em>if</em> you put relationals below OR, as I have done.</p>
<h2>UTF-8 decoding</h2>
<p>The following line of C(++) code decodes a 4-byte UTF-8 sequence to the corresponding Unicode code point (after the validity check has been done):</p>
<pre><code>code_point = ((bytes[0] &amp; 7) &lt;&lt; 18) | ((bytes[1] &amp; 0x3F) &lt;&lt; 12) | ((bytes[2] &amp; 0x3F) &lt;&lt; 6) | (bytes[3] &amp; 0x3F);
</code></pre>
<p>You could make the parentheses unnecessary by using the precedence order:</p>
<ol>
<li>AND (<code>&amp;</code>)</li>
<li>Shifts (<code>&lt;&lt;</code>, <code>&gt;&gt;</code>)</li>
<li>OR (<code>|</code>)</li>
</ol>
<p>Note that this switches the relative precedence of AND and shifting compared to the previous example.</p>
<h1>If you want to minimize confusion</h1>
<p>As @kaya3 pointed out, if you use the C syntax for operators, people will expect them to <em>work</em> the same as in C.  Just as if you allow C-style <code>;</code>, people will expect statement termination semantics to be the same as in C — <a href="https://stackoverflow.com/questions/2846283/what-are-the-rules-for-javascripts-automatic-semicolon-insertion-asi">to the confusion of JavaScript developers</a>.</p>
<p>So, <em>if</em> you're committed to the symbols <code>&lt;&lt;</code>, <code>&gt;&gt;</code>, <code>~</code>, <code>&amp;</code>, <code>|</code>. and <code>^</code>, it would probably be a good idea to keep C's precedence hierarchy for them.</p>
<p>If you decide to spell the operators differently (e.g., the word-like <code>lshift</code>, <code>rshift</code>, <code>not</code>, <code>and</code>, <code>or</code>, and <code>xor</code>), then this argument might not apply as much.</p>

CC BY-SA 4.0
2024-03-26T20:12:36.607Z
2024-03-26T20:12:36.607Z
dan04
<h1>Just use function call syntax</h1>
<p>In most kinds of programming, bitwise operators tend to be used very rarely, so most programmers are not going to remember their precedence rules. Given the rarity, what is even the point of having dedicated syntax for them? One could make them use the same syntax as regular function calls, where the precedence is unambigous:</p>
<pre class="lang-python prettyprint-override"><code>def bitset_contains(bitset: int, item: int) -&gt; bool:
    return bit_and(bitset, bit_left_shift(1, item)) != 0
</code></pre>

CC BY-SA 4.0
2024-04-22T10:54:28.873Z
2024-04-22T10:54:28.873Z
xigoi
<p>The precedence should be the same as it is in C, for several reasons.</p>
<h2>C got it right</h2>
<p>C got the relative precedences for these operators right*, so there's nothing to fix by changing it:</p>
<ul>
<li><code>~</code> has the highest precedence, by analogy with logical operators. It's also very common to use <code>~</code> to invert a mask that you want to apply with <code>&amp;</code>, so <code>~</code> should have higher precedence than <code>&amp;</code>.</li>
<li>Shifts have the next-highest because usually one or both sides are literals or other fixed constants, i.e. things which require no bitwise operations to compute. Shifts are also analogous to exponentiation (<code>1 &lt;&lt; n</code> equals <code>2 ** n</code>) which has a high precedence in arithmetic.</li>
<li><code>&amp;</code> has lower precedence than shifts because often you want to shift something to the correct position, and then use <code>&amp;</code> to keep just some of the bits, like <code>x &gt;&gt; offset &amp; mask</code>. If the mask is something like <code>0xFF</code> then you can clearly see that the result will only have the lowest 8 bits; this is more readable than <code>(x &amp; mask) &gt;&gt; offset</code> because the mask no longer shows which bits might be set in the result.</li>
<li><code>^</code> and <code>|</code> have lower precedence than <code>&amp;</code> both by analogy to logical operators, and because it's common to use them to combine the results of multiple shifts or masked-shifts. The relative precedence of <code>^</code> and <code>|</code> doesn't have much practical importance because there are few reasons to use them together.</li>
</ul>
<p><sub>*By &quot;right&quot;, I mean C avoids requiring parentheses as much as possible for the most common uses of bitwise operators, and also matches the relative precedences of analogous operators in mathematics. Of course there's some room for debate over which uses are most common and which mathematical operators are more analogous, but no design rationale can be perfectly objective.</sub></p>
<h2>Compatibility with C is important</h2>
<p>There are a lot of clever things you can do with bitwise operators, but most programmers will not invent their own new clever things. If people use bitwise operators, it's mostly in code they copy-paste from Stack Overflow, or popular articles such as <a href="https://graphics.stanford.edu/%7Eseander/bithacks.html" rel="nofollow noreferrer">this one</a>.</p>
<p>These sources will invariably assume C's precedence rules for bitwise operators, either because they are written in C, or because they are written in other languages with the same precedence rules for bitwise operators (and that's every other popular language with bitwise operators, as far as I know).</p>
<p>Therefore, your users' interests are best served by not adding an extra step that must be taken when translating such code into your language, particularly an extra step which users don't necessarily know they need to take.</p>
<h2>Users won't learn the precedences</h2>
<p>For bitwise operators (and sometimes even boolean logical operators!) it's often recommended to use parentheses to clarify the order of operations, even when parentheses would be redundant. Because even if <em>you</em> know the bitwise operator precedences, most of the people who will read your code do not.</p>
<p>The vast majority of programmers do not use these operators very often, and will not spend the effort to memorise their precedences. (This is especially the case for the relative precedences of bitwise and non-bitwise operators, like <code>&lt;&lt;</code> and <code>+</code>.) So, if people will use brackets anyway, you don't gain anything by giving them different precedences. Put another way, this isn't an efficient use of your language's <a href="https://steveklabnik.com/writing/the-language-strangeness-budget" rel="nofollow noreferrer">strangeness budget</a>.</p>

CC BY-SA 4.0
2024-03-25T18:02:49.703Z
2024-04-22T12:17:15.827Z
2024-04-22T12:17:15.827Z
kaya3
CC BY-SA 4.0
2024-03-25T23:38:59.110Z
This is exactly the answer I was looking for, thank you.
Now, everything is not right in the C precedence table, the biggest default being that the level of `=` is above `&`, `^` and `|` as I'm sure you know, but you've convinced me that the relative precedence of the bitwise operators should be kept as is.
WhiteMist
CC BY-SA 4.0
2024-03-25T23:39:09.413Z
A caveat about giving shifts higher precedence than AND is that it makes shift-then-mask easier to write, which in C unfortunately also makes it easier to get undefined or wrongly sign-extended results, than mask-then-shift; so if you are copying C’s precedence, it’s better *not* to copy its integer conversion rules. Another is that `<<` and `>>`, being digraphs, are wider than `&`, which can make people misread them as having lower precedence—for much the same reason as beginners often expect `a * b+c` to mean `a * (b + c)`.
Jon Purdy
CC BY-SA 4.0
2024-03-26T04:10:18.760Z
High precedence for shift is useful when you're shifting the mask, e.g. `x | 1 << n` is the standard idiom for setting bit n.
Barmar
CC BY-SA 4.0
2024-03-26T14:25:36.283Z
@Barmar That's an example of using `|` to combine the result of a shift with something else. If it's to update a bitset then `|=` is more common, though.
kaya3
CC BY-SA 4.0
2024-03-26T15:15:16.133Z
Good point about `|=`. The point of my comment is that this is less likely to run into overflow or bad sign extension.
Barmar
CC BY-SA 4.0
2024-03-28T17:08:11.843Z
One note to add about C is that the precedence of the bitwise operators `|`, `&` and `^` is lower than the presence of the comparison operators, which is normally considered a mistake.
CoffeeTableEspresso
# What should be the precedence of the bitwise operators relative to each others?
Posted by: username_0 on 2024-03-25
In C, the relative precedence of bitwise operators is as follows, from high to low precedence:
~       bitwise NOT
<< >>   bitwise left shift and right shift
&       bitwise AND
^       bitwise XOR
|       bitwise OR

It makes sense that ~ have a higher precedence than & which itself have a higher precedence than |, by analogy to the precedence of logical operators.
What I'm wondering is if the precedence of bitwise XOR ^ is right or if maybe it should be on the same level as bitwise OR |?
Additionally, I'm wondering what is the rationale for having the precedence of the bitwise shift operators << and >> where it is and if it corresponds to their regular use cases, specifically in relation with bitwise AND &? If it is in an awkward position, where should it be ideally?
**Tags:** syntax operators precedence bitwise-operators
> **Comments:**
> **username_1**: Are you designing a new language that uses these same operators?  
> **username_0**: @EricLippert I'm trying to design a language that have **these** operators period, yes. I don't understand your comment, having these operators is the norm in every imperative and scripting languages.  
> **username_1**: These are common choices; I would encourage you to look at more languages if you genuinely think these are the only choices, or the best choices. My question was intended to clarify whether you were asking about historical defects in the design of C that we're now aware of with the benefit of hindsight, or if you were asking to inform the design of a new language.  
> **username_2**: There's also the possibility of _incomparable_, non-transitive, precedences, [as in Fortress](https://softwareengineering.stackexchange.com/a/391296/271624) and some other language I don't remember ATM. (See also ["Fortress Features and Lessons Learned"](https://labs.oracle.com/pls/apex/f?p=94065:10:2849938467431:5316).)  
> **username_3**: As currently set out this question seems to be asking just for opinions, which isn't a kind of question that works well here, but if it were seeking *evidence* specifically (e.g. from empirical studies of bugs or defect rates, user studies on comprehensibility, languages being forced to change precedence rules) then it would make for a strong question. Alternatively, it could focus on the historical elements that are already there ("what is the rationale for...") and would then be a [tag:history] question about this traditional set of operations. It can't really be both, but which do you want?  
> **username_4**: To me it is logical that the bitwise shift operators have high precedence as they are sort of 'equivalent/most similar' to multiplication/exponentiation. And bitwise OR is the most similar to addition and has the lowest.  
---
## 3 answers
### Answer by username_7 on 2024-03-25. Score: 5 | Accepted answer
The precedence should be the same as it is in C, for several reasons.

## C got it right

C got the relative precedences for these operators right\*, so there's nothing to fix by changing it:

* `~` has the highest precedence, by analogy with logical operators. It's also very common to use `~` to invert a mask that you want to apply with `&`, so `~` should have higher precedence than `&`.
* Shifts have the next-highest because usually one or both sides are literals or other fixed constants, i.e. things which require no bitwise operations to compute. Shifts are also analogous to exponentiation (`1 << n` equals `2 ** n`) which has a high precedence in arithmetic.
* `&` has lower precedence than shifts because often you want to shift something to the correct position, and then use `&` to keep just some of the bits, like `x >> offset & mask`. If the mask is something like `0xFF` then you can clearly see that the result will only have the lowest 8 bits; this is more readable than `(x & mask) >> offset` because the mask no longer shows which bits might be set in the result.
* `^` and `|` have lower precedence than `&` both by analogy to logical operators, and because it's common to use them to combine the results of multiple shifts or masked-shifts. The relative precedence of `^` and `|` doesn't have much practical importance because there are few reasons to use them together.

\*By "right", I mean C avoids requiring parentheses as much as possible for the most common uses of bitwise operators, and also matches the relative precedences of analogous operators in mathematics. Of course there's some room for debate over which uses are most common and which mathematical operators are more analogous, but no design rationale can be perfectly objective.

## Compatibility with C is important

There are a lot of clever things you can do with bitwise operators, but most programmers will not invent their own new clever things. If people use bitwise operators, it's mostly in code they copy-paste from Stack Overflow, or popular articles such as [this one](https://graphics.stanford.edu/%7Eseander/bithacks.html).

These sources will invariably assume C's precedence rules for bitwise operators, either because they are written in C, or because they are written in other languages with the same precedence rules for bitwise operators (and that's every other popular language with bitwise operators, as far as I know).

Therefore, your users' interests are best served by not adding an extra step that must be taken when translating such code into your language, particularly an extra step which users don't necessarily know they need to take.

## Users won't learn the precedences

For bitwise operators (and sometimes even boolean logical operators!) it's often recommended to use parentheses to clarify the order of operations, even when parentheses would be redundant. Because even if *you* know the bitwise operator precedences, most of the people who will read your code do not.

The vast majority of programmers do not use these operators very often, and will not spend the effort to memorise their precedences. (This is especially the case for the relative precedences of bitwise and non-bitwise operators, like `<<` and `+`.) So, if people will use brackets anyway, you don't gain anything by giving them different precedences. Put another way, this isn't an efficient use of your language's [strangeness budget](https://steveklabnik.com/writing/the-language-strangeness-budget).
> **Comments:**
> **username_0** (2024-03-25): This is exactly the answer I was looking for, thank you.
Now, everything is not right in the C precedence table, the biggest default being that the level of `=` is above `&`, `^` and `|` as I'm sure you know, but you've convinced me that the relative precedence of the bitwise operators should be kept as is.  
> **username_8** (2024-03-25): A caveat about giving shifts higher precedence than AND is that it makes shift-then-mask easier to write, which in C unfortunately also makes it easier to get undefined or wrongly sign-extended results, than mask-then-shift; so if you are copying C’s precedence, it’s better *not* to copy its integer conversion rules. Another is that `<<` and `>>`, being digraphs, are wider than `&`, which can make people misread them as having lower precedence—for much the same reason as beginners often expect `a * b+c` to mean `a * (b + c)`.  
> **username_9** (2024-03-26): High precedence for shift is useful when you're shifting the mask, e.g. `x | 1 << n` is the standard idiom for setting bit n.  
> **username_7** (2024-03-26): @Barmar That's an example of using `|` to combine the result of a shift with something else. If it's to update a bitset then `|=` is more common, though.  
> **username_9** (2024-03-26): Good point about `|=`. The point of my comment is that this is less likely to run into overflow or bad sign extension.  
> **username_10** (2024-03-28): One note to add about C is that the precedence of the bitwise operators `|`, `&` and `^` is lower than the presence of the comparison operators, which is normally considered a mistake.  
---
### Answer by username_5 on 2024-03-26. Score: 2
If you want to minimize the need for parentheses
Let's typical use case of bitshift/masking operations.
Bit arrays
Suppose that you have a bit array class, allowing an integer (or array of integers) to be treated as an array of bits.  It provides the operations:

get bitarray[i] → if ((backing_int & (1 << i)) != 0)
set bitarrary[i] = value → backing_int = (backing_int & ~(1 << i)) | (value << i)

To make these work without parentheses, you would need the precedence order:

Shifts (<< and >>)
NOT (~)
AND (&)
OR (|)
Relationals (==, !=, etc.)

Note that I only used left shift (<<), not right shift (>>), but since these are parallel and inverse operators, similar to + and -, it would be weird to not have them at the same precedence level.
Also, I didn't include XOR (^) in my example.  If you think of XOR as being a one-bit addition (with the carry bit ignored), then it makes sense to place it below AND (which is a one-bit multiplication).  If you think of XOR as being a Boolean != operator, it makes sense to treat them at the same level as relationals — if you put relationals below OR, as I have done.
UTF-8 decoding
The following line of C(++) code decodes a 4-byte UTF-8 sequence to the corresponding Unicode code point (after the validity check has been done):
code_point = ((bytes[0] & 7) << 18) | ((bytes[1] & 0x3F) << 12) | ((bytes[2] & 0x3F) << 6) | (bytes[3] & 0x3F);

You could make the parentheses unnecessary by using the precedence order:

AND (&)
Shifts (<<, >>)
OR (|)

Note that this switches the relative precedence of AND and shifting compared to the previous example.
If you want to minimize confusion
As @kaya3 pointed out, if you use the C syntax for operators, people will expect them to work the same as in C.  Just as if you allow C-style ;, people will expect statement termination semantics to be the same as in C — to the confusion of JavaScript developers.
So, if you're committed to the symbols <<, >>, ~, &, |. and ^, it would probably be a good idea to keep C's precedence hierarchy for them.
If you decide to spell the operators differently (e.g., the word-like lshift, rshift, not, and, or, and xor), then this argument might not apply as much.
---
### Answer by username_6 on 2024-04-22. Score: 0
Just use function call syntax
In most kinds of programming, bitwise operators tend to be used very rarely, so most programmers are not going to remember their precedence rules. Given the rarity, what is even the point of having dedicated syntax for them? One could make them use the same syntax as regular function calls, where the precedence is unambigous:
def bitset_contains(bitset: int, item: int) -> bool:
    return bit_and(bitset, bit_left_shift(1, item)) != 0
---
