You are probably familiar with the word “beat”. If not, let's get to know it :) A bit is the minimum unit of measurement of information in a computer. Its name comes from the English “ binary digit ” - “binary number”. A bit can be expressed as one of two numbers: 1 or 0. There is a special number system based on ones and zeros - binary. We won’t delve into the jungle of mathematics and just note that any number in Java can be converted to its binary form. To do this you need to use wrapper classes. For example, here's how to do it for a number
All operations are performed from left to right, but taking into account their priority. For example, if we write:
int
:
public class Main {
public static void main(String[] args) {
int x = 342;
System.out.println(Integer.toBinaryString(x));
}
}
Console output:
101010110
1010 10110 (I added a space for readability) is the number 342 in binary. We actually divided this number into individual bits - zeros and ones. It is with them that we can perform operations called bitwise.
-
~
— bitwise “NOT” operator.
00000000 00000000 00000001 01010110
- the number 342 in a variable of type int in java 11111111 11111111 11111110 10101001
- the result of the expression ~342 in java Let's try to do this in practice:
public class Main {
public static void main(String[] args) {
int x = 342;
System.out.println(Integer.toBinaryString(~x));
}
}
Console output:
11111111111111111111111010101001
-
&
— bitwise operator “AND”
&&
). The operator &&
, as you remember, returns true
only if both operands are true. Bitwise &
works in a similar way: it compares two numbers bit by bit. The result of this comparison is the third number. For example, let's take the numbers 277 and 432: 100010101 - the number 277 in binary form 110110000 - the number 432 in binary form Next, the operator &
compares the first bit of the upper number with the first bit of the lower one. Since this is an “AND” operator, the result will be equal to 1 only if both bits are equal to 1. In all other cases, the result will be 0. 100010101 &
110110000 _______________ 100010000 - result of work &
We first compare the first bits of two numbers with each other, then second bits, third, etc. As you can see, only in two cases were both bits in the numbers equal to 1 (the first and fifth bits). The result of all other comparisons was 0. Therefore, in the end we got the number 100010000. In the decimal system, it corresponds to the number 272. Let's check:
public class Main {
public static void main(String[] args) {
System.out.println(277&432);
}
}
Console output:
272
|
- bitwise “OR”. The principle of operation is the same - we compare two numbers bit by bit. Only now if at least one of the bits is equal to 1, the result will be equal to 1. Let's look at the same numbers - 277 and 432:
|
110110000 _______________ 110110101 - the result of the work. |
Here the result is different: only those bits that were zeros in both numbers remained zeros. The result of the work is the number 110110101. In the decimal system it corresponds to the number 437. Let’s check:
public class Main {
public static void main(String[] args) {
System.out.println(277|432);
}
}
Console output:
437
We counted everything correctly! :)
^
- bitwise exclusive OR (also known as XOR)
true
if at least one operand is true. But not necessarily one - if both are there true
- then the result true
. But the exclusive “or” returns true
only if one of the operands is true. If both operands are true, a regular “or” will return true
(“at least one is true”), but an exclusive or will return false
. That's why it's called exclusive. Knowing the principle of previous bitwise operations, you can probably easily perform the 277^432 operation yourself. But let’s better figure it out together once again :) 100010101 ^
110110000 _______________ 010100101 - the result of the work ^
Here is our result. Those bits that were the same in both numbers returned 0 (the “one of” formula did not work). But those that formed a pair 0-1 or 1-0 eventually turned into a unit. As a result, we got the number 010100101. In the decimal system, it corresponds to the number 165. Let's see if we calculated correctly:
public class Main {
public static void main(String[] args) {
System.out.println(277^432);
}
}
Console output:
165
Super! Everything is exactly as we thought :) Now is the time to get acquainted with the operations called bit shifts. The name, in principle, speaks for itself. We'll take some number and move its bits left and right :) Let's see what it looks like:
Shift left
Left shift of bits is indicated by the sign<<
Example:
public class Main {
public static void main(String[] args) {
int x = 64;//meaning
int y = 3;//quantity
int z = (x << y);
System.out.println(Integer.toBinaryString(x));
System.out.println(Integer.toBinaryString(z));
}
}
In this example, the number x=64
is called the value. It is its bits that we will shift. We will shift the bits to the left (this can be determined by the direction of the sign <<
) In the binary system, the number 64 = 1000000 The number y=3
is called quantity. Quantity answers the question “how many bits to the right/left should the bits of a number be shifted x
?” In our example, we will shift them 3 bits to the left. To make the shift process more clear, let's look at the picture. In our example we use numbers of type int. Int
's occupy 32 bits of computer memory. This is what our original number 64 looks like: And now we, in the literal sense of the word, take each of our bits and shift it to the left by 3 cells: This is what we got. As you can see, all our bits have shifted, and 3 more zeros have been added from outside the range. 3 - because we were shifting by 3. If we were shifting by 10, 10 zeros would be added. So the expression x << y
means “shift the bits of a number х
y cells to the left.” The result of our expression was the number 1000000000, which in the decimal system is equal to 512. Let's check:
public class Main {
public static void main(String[] args) {
int x = 64;//meaning
int y = 3;//quantity
int z = (x << y);
System.out.println(z);
}
}
Console output:
512
That's right! In theory, bits can be shifted indefinitely. But since we have the number int
, there are only 32 cells available. Of these, 7 are already occupied by the number 64 (1,000,000). Therefore, if we make, for example, 27 shifts to the left, our only unit will go out of range and “overwrite”. Only zeros will remain!
public class Main {
public static void main(String[] args) {
int x = 64;//meaning
int y = 26;//quantity
int z = (x << y);
System.out.println(z);
}
}
Console output:
0
As we expected, the one went beyond the 32 bit cells and disappeared. We got a 32-bit number consisting of only zeros. Naturally, in the decimal system it corresponds to 0. A simple rule for remembering left shifts: With each left shift, the number is multiplied by 2. For example, let's try to calculate the result of the expression without pictures with bits. 111111111 << 3
We need to multiply the number 111111111 by 2 three times. As a result, we get 888888888. Let's write the code and check it:
public class Main {
public static void main(String[] args) {
System.out.println(111111111 << 3);
}
}
Console output:
888888888
Right shifts
They are indicated by the sign>>
. They do the same thing, only in the other direction! :) Let's not reinvent the wheel and try to do this with the same number int 64.
public class Main {
public static void main(String[] args) {
int x = 64;//meaning
int y = 2;//quantity
int z = (x >> y);
System.out.println(z);
}
}
As a result of the shift by 2 to the right, the two extreme zeros of our number went outside the range and were erased. We got the number 10000, which in the decimal system corresponds to the number 16. Output to the console:
16
A simple rule for remembering right shifts: Each right shift divides by two, discarding any remainder. For example, 35 >> 2
it means that we need to divide 35 by 2 2 times, discarding the remainder 35/2 = 17
(discarding remainder 1) 17:2 = 8
(discarding remainder 1) Total 35 >> 2
should be equal to 8. Check:
public class Main {
public static void main(String[] args) {
System.out.println(35 >> 2);
}
}
Console output:
8
Precedence of operations in Java
As you write or read code, you will often come across expressions in which several operations are performed simultaneously. It is very important to understand in what order they will be performed, otherwise the result may be unexpected. Since there are many operations in Java, they were all separated into a special table:Operator Precedence
Operators | Precedence |
---|---|
postfix | expr++ expr-- |
unary | ++expr --expr +expr ~ ! |
Multiplicative | * / % |
additive | + - |
shift | << >> >>> |
relational | < > <= >= instanceof |
equality | == != |
bitwise AND | & |
bitwise exclusive OR | ^ |
bitwise inclusive OR | | |
logical AND | && |
logical OR | || |
ternary | ? : |
assignment | = += -= *= /= %= &= ^= |= <<= >>= >>>= |
int x = 6 - 4/2;
first the division operation (4/2) will be performed. Although she is second in line, she has higher priority. Parentheses or square brackets change any priority to maximum. You probably remember this from school. For example, if you add them to an expression: int x = (6 - 4)/2;
the subtraction will be performed first, since it is calculated in parentheses. The logical operator has &&
a rather low priority, as can be seen from the table. Therefore, most often it will be executed last. For example: boolean x = 6 - 4/2 > 3 && 12*12 <= 119;
This expression would be executed like this:
-
4/2 = 2
boolean x = 6 - 2 > 3 && 12*12 <= 119;
-
12*12 = 144
boolean x = 6 - 2 > 3 && 144 <= 119;
-
6-2 = 4
boolean x = 4 > 3 && 144 <= 119;
-
Next the comparison operators will be executed:
4 > 3 = true
boolean x = true && 144 <= 119;
-
144 <= 119 = false
boolean x = true && false;
-
And finally, the last operator will be executed
&&
.boolean x = true && false;
boolean x = false;
The addition operator (
+
), for example, has higher precedence than the comparison operator!=
(“not equal”);Therefore in the expression:
boolean x = 7 != 6+1;
first the operation 6+1 will be performed, then the check 7!=7 (false), and at the end the result will be assigned to
false
the variablex
. Assignment generally has the lowest priority of all operations - look in the table.
- Logical Operators - JavaRush lecture on logical operations. We won’t get to them any time soon, but you can read them now, there won’t be any harm
GO TO FULL VERSION