binary stuff

In the relationship between character set and character encoding , it is introduced that the internal circuit of the computer determines that the information of the computer can only be processed by binary numbers. This issue will introduce those things in binary.

shift operation

The shift operation refers to the operation of shifting each digit of a binary value to the left and right . The low-order bits vacated by the left shift need to be filled with 0s, and the high-order bits vacated by the right shift will be explained later.
image.png

We found that shifting left by two bits is equivalent to multiplying 39 by 4, and shifting right by two bits is equivalent to dividing by 4. That is to say, the computer uses the shift algorithm to represent the multiplication and division of data .

Complement

All the content related to the right shift was not introduced just now, because the value used to fill the high-order bits vacated after the right shift has two forms: 0 and 1. To distinguish when to add 0 and when to add 1, as long as you master the method of using binary numbers to represent negative numbers.

When negative numbers are represented in binary numbers, the highest bit is generally used as the sign, that is, the highest bit is the sign bit. The sign bit of positive numbers is represented by 0, and the sign bit of negative numbers is represented by 1. For example, the binary number of 1 is 0000 0001, so what is the binary number of -1? Is it 1000 0001, the result of 1000 0001+0000 0001 is not 0, indicating that the result is wrong. For this reason, one's complement is required when representing negative numbers . The complement is to use positive numbers to represent negative numbers, by inverting all the values ​​of the binary numbers, and then adding 1 to the result to get the complement . -1's complement is 1111 1111. Similarly, what is the negative number represented by 1111 1110? At this time, we can use the property of negative and positive . Assuming 1111 1110 is negative xx, then the complement of 1111 1110 is positive xx. The complement of 1111 1110 is 0000 0010, so 1111 1110 means -2.

Logical shift right and arithmetic right shift

After introducing the complement number, let us return to the topic of right shift. After right shift, there are two cases of complement 0 and complement 1 in the highest bit. When the value of the binary number represents a graphics mode rather than a numerical value, the highest bit is filled with 0 after shifting, which is a logical right shift . When operating a binary value as a signed value, the most significant bit is filled with the value of the previous sign bit ( 0 or 1 ) after shifting, which is an arithmetic right shift .

Now let's look at an example of a right shift. Shift -8 (1111 1000) two places to the right. At this time, in the case of logical right shift, the result will be 0011 1110, that is, the decimal number 62, which is obviously not -2, and in the case of arithmetic right shift, the result will become 1111 1110, which is -2 in complement. same as the real result. Note that logical shifts and arithmetic shifts are only distinguished when shifting right.

Binary numbers represent decimals

Through the above introduction, we have explained the binary representation of integers. Since all information inside the computer is processed in the form of binary numbers, there is no difference between integers and decimals at this point. However, using binary numbers to represent integers and decimals is very different.

Since the numerical range of decimals represented by binary numbers is limited, it cannot represent all decimals. For example, when the 3 digits after the decimal point are represented by binary numbers, the value range is 0.000~0.111, but only limited decimal fractions can be represented, as shown in the following figure.
image.png
In order to deepen everyone's impression, let's take a more practical chestnut: the final result of accumulating 0.1 100 times is 10.000002, not 10.

public class TestBinary {
    public static void main(String[] args) {
        float sum=0.0f;
        for (int i = 0; i < 100; i++) {
            sum += 0.1;
        }
        System.out.println(sum);

    }
}

floating point number

Now, we should know that only binary numbers on paper can't represent all decimals. So, what kind of representation does the computer actually use to deal with decimals?

Currently, computers provide single-precision floating-point numbers and double-precision floating-point numbers to represent fractional forms. Single-precision floating-point numbers use 32 bits to represent all decimals, while double-precision floating-point numbers use 64 bits. They all consist of sign, mantissa and exponent.
image.png

Next, let's see if 0.1 is represented by a single-precision floating-point number, and the result of accumulating 100 times is 10. The result is unexpected again, and the result is 10.000002.

public class TestBinary {
    public static void main(String[] args) {
        float sum=0.0f;
        float step = 0.1f;
        for (int i = 0; i < 100; i++) {
            sum += step;

        }
        System.out.println(sum);

    }
}

How to Avoid Computer Calculation Errors

We know that there is a possibility of miscalculation whether we use paper binary or floating point numbers to represent decimals, so how can we avoid this problem?

The first is an avoidance strategy, which is ignoring the problems. Sometimes small deviations don't cause any problems. Second, convert the decimal to an integer to calculate . Or take 0.1 accumulating 100 times as an example, expand 0.1 by 10 times and accumulate 100 times, and finally divide the result by 10.

public class TestBinary {
    public static void main(String[] args) {
        int sum=0;
        int step = 1;
        for (int i = 0; i < 100; i++) {
            sum += step;

        }
        System.out.println(sum/10);

    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324934505&siteId=291194637