C language - data storage (binary form)

Summary: 1. Detailed introduction of data types 2. Storage of integers in memory: original code, inverse code, complement code 3. Introduction and judgment of big and small endian byte order 4. Storage and analysis of floating-point types in memory.

1. Data type

The plastic surgery family mainly includes:

char unsigned char signed char
short unsigned short  signed short 
int unsigned int signed int
long unsigned long signed long

The floating-point family mainly includes:

float double

Construction type:

array type Structure type enumerated type union type

Pointer type:

int *pi; char *pc; float* pf; void* pv;

empty type:

  void means empty type (no type) It is usually applied to the return type of the function, the parameter of the function, and the pointer type.

2. Original code, inverse code, complement code

There are three binary representation methods for integers in computers, namely original code, complement code and complement code. The three representation methods all have two parts, a sign bit and a value bit. The sign bit uses 0 to represent "positive" and 1 to represent "negative" . There are three different ways of representing negative integers.

Original code: The original code can be obtained by directly translating the value into binary in the form of positive and negative numbers.

Inverse code: The sign bit of the original code remains unchanged, and the other bits are sequentially inverted to obtain the inverse code.

Complementary code: Complementary code is obtained by inverse code +1.

3. Big and small endian introduction

Big endian (storage) mode means that the low bits of data are stored in the high addresses of the memory, while the high bits of data are stored in the low addresses of the memory; little endian (storage) mode means that the low bits of data are stored in the low addresses of the memory address, while the high bits of the data are stored in the high address of the memory.

For example, int a = 1 in the figure (hexadecimal representation)                                     

01 (low address) 00 00 00 (high address)

4. Storage analysis of integer and floating point types in memory

Shaping:

signed char (complement form) unsigned char
00000000(0) 00000000(0)
00000001(1) 00000001(1)
。。。 。。。
10000001(-127) 10000001(129)
111111110(-2) 111111110(254)
111111111(-1) 111111111(255)

What is the output of the following program?  


#include <stdio.h>
int main()
{
    char a= -1;
    signed char b=-1;
    unsigned char c=-1;
    printf("a=%d,b=%d,c=%d",a,b,c);//整形提升正数补0负数补1
//a:10000000000000000000000000000001(-1)原码
//b:10000000000000000000000000000001(-1)原码
//c:00000000000000000000000011111111(225)
    return 0;
}

Float:

According to the international standard IEEE (Institute of Electrical and Electronics Engineering) 754, any binary floating-point number V can be expressed in the following form: (-1)^S * M * 2^E (-1)^S represents the sign bit, when S =0, V is a positive number; when S=1, V is a negative number. M represents a valid number, greater than or equal to 1 and less than 2. 2^E means exponent bits.

For example: 5.0 in decimal is 101.0 in binary, which is equivalent to 1.01×2^2. Then, according to the format of V above, it can be concluded that S=0, M=1.01, and E=2. Decimal -5.0, written in binary is -101.0, which is equivalent to -1.01×2^2. Then, S=1, M=1.01, E=2.

Note that .1 after the binary point is 0.5 in decimal. .01 is 0.25. .11 is 0.75 and so on.

Under thirty-two:

sign bit index bit index bit index bit index bit index bit index bit index bit index bit effective number valid value effective number effective number effective number effective number effective number effective number effective number effective number effective number 。。。

EEE 754 has some special regulations on the significant figures M and exponent E. As mentioned earlier, 1≤M<2, that is to say, M can be written in the form of 1.xxxxxx, where xxxxxx represents the decimal part. IEEE 754 stipulates that when M is saved inside the computer, the first digit of this number is always 1 by default, so it can be discarded, and only the following xxxxxx part is saved. For example, when saving 1.01, only save 01, and then add the first 1 when reading. The purpose of doing this is to save 1 significant figure. Taking the 32-bit floating point number as an example, there are only 23 bits left for M. After the first 1 is rounded off, it is equivalent to saving 24 significant figures.

As for the index E, the situation is more complicated.

First, E is an unsigned integer (unsigned int) which means that if E is 8 bits, its value range is 0~255; if E is 11 bits, its value range is 0~2047.

However, we know that E in scientific notation can have negative numbers, so IEEE 754 stipulates that an intermediate number must be added to the real value of E when stored in memory. For 8-digit E, the intermediate number is 127; For an 11-bit E, this intermediate number is 1023. For example, the E of 2^10 is 10, so when saving it as a 32-bit floating point number, it must be saved as 10+127=137, which is 10001001. Then, the index E is fetched from the memory and can be further divided into three cases: 

E is not all 0 or not all 1 At this time,

  Floating-point numbers are represented by the following rules, that is, subtract 127 (or 1023) from the calculated value of the exponent E to obtain the real value, and then add the first 1 before the effective number M. For example: the binary form of 0.5 (1/2) is 0.1, since the positive part must be 1, that is, the decimal point is shifted to the right by 1, then it is 1.0*2^(-1), and its order code is -1+127= 126, expressed as 01111110, and the mantissa 1.0 removes the integer part to be 0, and fills 0 to 23 digits 000000000000000000000000, then its binary representation is:

0 01111110 00000000000000000000000

E is all 0 at this time,

  The exponent E of the floating-point number equal to 1-127 (or 1-1023) is the real value, and the effective number M is no longer added with the first 1, but is restored to a decimal of 0.xxxxxx. This is done to represent ±0, and very small numbers close to 0.

E is all 1 at this time,

If the significant number M is all 0, it means ±infinity (positive or negative depends on the sign bit s);

         Thanks for watching~

Guess you like

Origin blog.csdn.net/m0_74358683/article/details/131010250