C language - binary/shift operator/bit operator_study notes

For more knowledge about the storage of data in memory, welcome to browse C language - Storage of data in memory_study notes

binary

Binary related conceptual knowledge

Binary can be said to be a number system specially designed for computers. In this system, there are only two numbers, 0 and 1, and the carry rule is "every two carries one."

Binary is still very meaningful to computers. Computers perform relevant calculations through a series of hardware connected through electronic circuits.

In computer circuits, binary numbers are usually represented using logic signals, that is, there are only two states in the circuit: high level and low level. Among them, high level represents 1 in binary number, while low level represents 0 in binary number.

Binary to decimal

The weight of each bit in the binary system, from right to left, is: 2 to the power 0, 2 to the power 1, 2 to the power 2... and so on.
For example: 1101 in binary, converted to decimal 13
Insert image description here

Decimal to binary

The decimal integer is converted into a binary integer using the method of "divide by 2, take remainder, and arrange in reverse order".

The specific method is: divide the decimal integer by 2, you can get a quotient and remainder; then divide the quotient by 2, you will get a quotient and remainder, and so on until the quotient is less than 1, and then use the remainder obtained first as a binary The low-order significant bits of the number are used as the high-order significant bits of the binary number, and the remaining remainders are arranged in sequence.
Insert image description here

Original code, inverse code, complement code

There are three binary representation methods of integers, original code, complement code and complement code.

The three representation methods have two parts: sign bit and numeric bit. In the binary sequence, the highest 1 bit is the sign bit, and the rest are numeric
bits. Among them, if the sign bit is 0, it means that the number is positive; if the sign bit is 1, it means that the number is negative;

The original code, complement code and complement code of positive integers are the same.

The exception is negative integers. The three codes of negative integers have different representation methods:
Original code: the sign bit is 1, and the numerical bit is the same as the numerical bit of the positive number. (The numerical bits of 5 and -5 are the same, the sign bit of -5 is 1, and the sign bit of 5 is 0)
Inverse code: The sign bit of the original code is unchanged, and the numerical bits are inverted bit by bit to obtain the inverse code.
Complement code: complement code + 1 to get the complement code.
Example: (In C language, in the VS2020 environment, an int type, the value -5, the binary related representation is as follows)
Insert image description here
For integer, the data is stored in the memory in the form of complement.

Let’s expand our knowledge here. Why in computers, values ​​are always expressed and stored in two’s complement
? The reason is: using two’s complement, sign bits and numerical bits can be processed uniformly; at the same time, addition and subtraction can also be processed uniformly (CPU only has adder. ) In addition, the operation process of converting complement code and original code to each other is the same, and it can be realized without designing additional hardware circuits.

Shift operator (the operand of the shift operator can only be an integer)

<<left shift operator (discard on the left, add 0 on the right)

Insert image description here

>>Right shift operator (there are two types of right shift operations)

1. Logical right shift: fill the left side with 0 and discard the right side

Insert image description here

2. Arithmetic right shift: fill the left side with the sign bit of the original value, and discard the right side

Insert image description here

PS: For the shift operator, do not move negative bits (such as 3 <<-1 or 3 >> -1), this is not defined by the standard.
PS: Generally, logical right shift is more common, and the right shift operation in the VS2020 environment is also a logical right shift.

Application of shift operators

  1. Quickly calculate powers
    . Shifting a number to the left by several powers is equivalent to multiplying it by 2 to several powers.
    Shifting a number to the right by several powers is equivalent to dividing it by 2 raised to several powers.
int num = 10;
# 10乘以23次方
result = x << 3

# 10除以2的n次方
result = x >> 3
  1. There are many application scenarios for using shift operators and bit operators together.

Bit operators

"&" bitwise AND

For two corresponding binary bits, the result is 1 only if both bits are 1, otherwise it is 0.

//例如:5 & 8 = 0
00000000 00000000 00000000 00000101 //5的补码(正整数的原码、反码、补码都一样)
00000000 00000000 00000000 00001000 //8的补码
————————————————————————————————————————————————————————————————————————————————
00000000 00000000 00000000 00000000 //结果为0

"|" bitwise OR

For two corresponding binary bits, as long as one of them is 1, the result is 1, and only when both bits are 0, the result is 0.

//例如:5 | 8 = 13
00000000 00000000 00000000 00000101 //5的补码(正整数的原码、反码、补码都一样)
00000000 00000000 00000000 00001000 //8的补码
————————————————————————————————————————————————————————————————————————————————
00000000 00000000 00000000 00001101 //结果为13

"^" bitwise OR

For two corresponding binary bits, the result is 1 when the two bits are different and 0 when the two bits are the same.

//例如:5 ^ 8 = 13
00000000 00000000 00000000 00000101 //5的补码(正整数的原码、反码、补码都一样)
00000000 00000000 00000000 00001000 //8的补码
————————————————————————————————————————————————————————————————————————————————
00000000 00000000 00000000 00001101 //结果为13

"~" bitwise negation

It flips every bit of the operand (including the sign bit)

//例如:~ 5 = -6
00000000 00000000 00000000 00000101 //5的补码(正整数的原码、反码、补码都一样)
————————————————————————————————————————————————————————————————————————————————
11111111 11111111 11111111 11111010 //一个负数的补码
10000000 00000000 00000000 00000101 //反码
10000000 00000000 00000000 00000110 //原码,结果为-6

The magic of bit operators

  1. Temporary variables cannot be created (that is, a third variable cannot be used) to achieve the exchange of two numbers.
#include <stdio.h>
int main()
{
    
    
	int a = 10;
	int b = 20;
	printf("交换前:a = %d b = %d\n", a, b);

	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	printf("交换后:a = %d b = %d\n", a, b);
	return 0;
}

Output result:

交换前:a = 10 b = 20
交换后:a = 20 b = 10
  1. Find the number of binary ones stored in memory for an integer.
#include <stdio.h>
int main()
{
    
    
	int num = -1;
	int i = 0;
	int count = 0;//计数
	while (num)
	{
    
    
		count++;
		num = num & (num - 1);
	}
	printf("二进制中1的个数 = %d\n", count);
	return 0;
}

Output result:

二进制中1的个数 = 32
  1. In an integer array, only one number appears once, and other arrays appear in pairs. Find the number that only appears once.
    For example:
    There are: 1 2 3 4 5 1 2 3 4 in the array. Only 5 appears once and other numbers appear twice. Find 5
#include <stdio.h>

int find_single_dog(int arr[], int sz)
{
    
    
    int ret = 0;
    int i = 0;
    for (i = 0; i < sz; i++)
    {
    
    
        ret ^= arr[i];
    }
    return ret;
}
int main()
{
    
    
    int arr[] = {
    
     1,2,3,4,5,1,2,3,4 };
    int sz = sizeof(arr) / sizeof(arr[0]);
    int dog = find_single_dog(arr, sz);
    printf("%d\n", dog);


    return 0;
}

Output results

5

Accumulation of knowledge points

1. n&(n-1)

Run this line of code once, and the rightmost 1 in the two's complement of n disappears.

In other words, if this line of code is run several times, it shows how many 1's there are in the two's complement of n. code show as below

#include <stdio.h>
int main()
{
    
    
	int n = 0;
	scanf("%d", &n);
	int count = 0;
	while (n)
	{
    
    
		n = n & (n - 1);
		count++;
	}
	printf("%d", count);
}

This expression can also be used to determine whether n is a power of 2. code show as below:

#include <stdio.h>
int main()
{
    
    
	int n = 0;
	scanf("%d", &n);
	if ((n & (n - 1) )== 0)
	{
    
    
		printf("YES\n");
	}
	else
	{
    
    
		printf("NO\n");
	}
}

Guess you like

Origin blog.csdn.net/yjagks/article/details/132529283