Data storage (2) (c language)

Following the previous article, we continue to study the storage of char type and floating point type data.

1.Char type data storage method

Just use the code to demonstrate it to everyone.

#include<stdio.h>
int main()
{
	char a[1000];
	int i;
	for (i = 0; i < 1000; i++)
	{
		a[i] = -1 - i;
	}
	printf("%d", strlen(a));
	return 0;
}

Reading this code, we can find that the value of i is paid to a[i], and the value of a[i] will be -1, -2, -3, ...., -999, -1000, as the cycle proceeds. But will it really print out -1000?

Certainly not

The problem arises in that the char type cannot store such small numbers, so next we will study the char type data in depth;

We all know that int type data occupies 4 bytes, while char type data only occupies one byte, so in terms of bits, the int type occupies 32 bits, while the char type only occupies 8 bits.

And the size of one bit can fit a binary

So their maximum value may be (here regarded as unsigned):

int 1111 1111 1111 1111 1111 1111 1111 1111(4,294,967,168)

char Same as 1111 1111 (255)

But we still have to consider that the first bit is the sign bit, 0 represents a positive number, and 1 represents a negative number.

Therefore, the largest number in the char type is expressed in binary as 0111 1111, which is 127 in decimal;

The smallest number in the char type is expressed in binary as    1000 0000 (-128). This is a fixed value. When this number appears in char, it will be directly regarded as -128.

And the binary value of char will cycle between -128 and 127 during operation, that is, when the binary value of 127 +1 will become -128, in the same way, it will start from -1 to -1, reduce to -128, and then reduce One will become 127, and it will cycle until it reaches zero.

So of course it’s not enough to save a number like -1000.

Let’s look at the strlen function again. We all know that strlen measures the length of a string and will not end until it encounters \0.

So the final output value is 127+128

Let's get the code running

Eh! Walk!

We can also turn this loop into a circle

 

This is very easy to understand 

2. Understand how floating point numbers are stored and processed

Let’s look at common floating point numbers first;

3.1415926 (just one with a decimal point)

1E10 (in scientific notation, representing 1.0×10^10)

The types of floating point numbers include: float, double, long double types

Continue to observe the following set of codes about floating point numbers.

#include<stdio.h>
int main()
{
	int n = 9;
	float* pfloat = (float*)&n;
	printf("n的值为:%d\n", n);
	printf("*pfloat*的值为:%f\n", *pfloat);
	*pfloat = 9.0;
	printf("num的值为:%d\n", n);
	printf("*pfloat的值为:%f\n", *pfloat);
	return 0;
}

 The following is the output result. Is it the same as you thought?

 We can first look at the two printed data above;

 

 The value of n is 9, which is integer type data. We then output integer type data, that is, %d output, and we find that the output is 9;

But when we define a float type pointer, this pointer points to the address of n. Finally, when we decode this pointer and output it, we find that it is 0.000000 and the integer output is not the same value.

That is to say, if we store the reshaped data 9 in it, and then use reshaping to take it out, it will still remain unchanged.

But when we still store the integer data but take it out with floating point data, it becomes different.

So we use this to prove that the storage rules of integers are different from the storage rules of floating point types;

The same output data below is opposite;

Use floating point data to store it, and use integer to take it out, it will output a string of things like this;

However, when data is stored in floating point data, it can be used normally when taken out as floating point data. This also shows that the storage rules of integer and floating point data are different;

So what's the difference?

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. (The number converted into binary is only 0/1, so 1≤M<2)

2^E represents the exponent bit.

It means

V is a binary floating point number, V=(-1)^S * M * 2^E. If in (-1)^S, S=0, then (-1)^S=1, then this V is Represents a positive number; if S=1, then (-1)^S=-1, then V represents a negative number;

Let's give an example

5.5

The single digit 5 ​​is converted into binary and expressed as 101;

The weight of the value after the decimal point becomes a negative number.

It will be easier to understand the weights as shown in the figure.

Then 5.5 is expressed in binary as 101.1. Move the decimal point and change it into scientific notation to become 1.011. According to the expression form of V mentioned above, it can be written as 5.5=(-1)^0* 1.011 *2^2, where ( -1)^0 means this is a positive number, 2^2 means moving the decimal point backward two places, because V=(-1)^S * M * 2^E, so S=0, M=1.011, E =2, so when the computer stores data, it only needs to store S, M, and E into the computer to achieve the effect of storing floating point numbers;

What we also need to know is

The float type is a 32-bit floating point type

 The double type is a 64-bit floating point type

 As mentioned before, 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 xxxxxx part behind is saved. When we take it out for use again, the computer adds before the decimal point 1. You can restore its value. The reason for doing this is to save bits to make the decimal more precise. Because double stores more digits after the decimal point than float, it has higher precision. Therefore, double is also called a double-precision floating point type, and float is a single-precision floating point type (it is not that double has twice the precision of float, but it can store more multi-bit)

But can all floating-point data be accurately saved?

①Storage of M

For example, we give a number 5.3

 By analogy, we will find that no matter how many digits of M we have to add later, we can never accurately express the true value of 3 after the decimal point.

Discovered by monitoring functions in our compiler

 Our f is indeed a little bit worse than 3

Therefore, some floating point numbers cannot be stored in the computer very accurately, and there is still a slight error.

②Storage of E

As for the index E, the situation is more complicated.
First, E is an 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 be
negative, so IEEE 754 stipulates that an intermediate number must be added to the real value of E when stored in memory. For an 8-bit E, this intermediate number is 127 ;For an 11-digit E, this intermediate number is 1023. For example, the E of 2^10 is 10, so when it is saved as a 32-bit floating point number, it must be saved as 10+127=137, which is 10001001.

Let's use code to demonstrate

int main()
{
	float f = 5.5;
	//101.1
	//科学计数法:(-1)^0 * 1.011 * 2^2
	//二进制存储:0 10000001 011 00000000000000000000
	//十六进制表示:40b00000
	return 0;
}

 If you look at it in binary, the first 0 means that the number is a positive number.

Because 2^2, E is 2, as mentioned above, an intermediate value must be added when storing E. Float is an eight-digit E, so add 127 and convert it to binary. Then 2+127 is 10000001 when converted to binary. The last one is M. As mentioned before, the decimal point and the numbers before the decimal point are discarded, and only the numbers after the decimal point are retained. Therefore, 011 is stored in M, and the following digits are filled with 0;

The above is the storage of data. I hope it will be helpful to you.

Guess you like

Origin blog.csdn.net/wangduduniubi/article/details/129337552