Take you to deeply analyze the storage of data in memory (below)

  • Last time we talked about the storage of integers in memory, so do you have the same question as I do—whether floating-point numbers are stored in the same way as integers? ?

    Not much to say, let's look directly at the following code

    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;
    }

    Let's think about it, what is the answer? ? ?

     Huh! ! ! Why is it different from what you thought? ? Is someone the same as I thought the answer was 9 9.000000 9 9.000000 at first?

    Let's look down:

 

  •  Let's think about it, when we put it in in the form of an integer and take it out in the form of an integer, we get our first answer 9, but when we put it in in the form of an integer and take it out in the form of a floating point number, it is not the answer we want. Does this mean that taking it out in the form of a floating point number in memory is different from taking it out in the form of an integer? There is a difference between the storage of integers in memory and the storage of floating point numbers .
  •  We also need to understand how this answer is generated, which requires us to understand the representation of floating-point numbers inside the computer.
  • According to the international standard IEEE (Institute of Electrical and Electronics Engineers) 754, any binary floating-point number V can be expressed as:
  • (-1)^S*M*2^E
  • (-1)^S represents the sign bit When s=0, V is an integer, when s=1, V is a negative number
  • M represents a valid number, greater than or equal to 1, less than 2
  • 2^E means prime number bits

  • Let's give an example: 5.0 in decimal is 101.0 in binary, which is equivalent to 1.01x2^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, binary is -101.0, which is equivalent to -1.01x2^2. Then, s=1, E=2, M=1.01


 

 

 

 IEEE 754 has special regulations on the valid numbers M and E. When 1<=M<=2, M can be represented as 1.xxxxxxxx, where xxxxxxxx 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 xxxxxxxx part is saved. For example, when saving 1.01, only 01 is saved, and when it is read, 1 is added .


Purpose: To save 1 effective 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 digits.


  • By the way, first E is an non-symbolic integer, which means that if the E bit 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 may appear negative, so under the regulations of IEEE754, the real value of memory E must be added with an intermediate number. For the 8-bit E, this intermediate value is 127. For 11 E, this intermediate value is 1023. For example, the E of 2^10 is 10, so when saving a 32-bit floating-point number, you must save 10+127, which is 10001001.

  • E can be further divided into three situations when it is taken out of memory:

  • The first case: E is not all 0 and 1

    • At this time, the floating-point number adopts the following rules, that is, subtract 127 from E to get the real value, and then add 1 in front of the effective number M. For example: the binary form of 0.5 (1/2) is 0.1. Since the integer part must be 1, the decimal point must be shifted by 1, which is 1.0*2 (-1). According to the rules, 127 is added to -1 to get 126, which is expressed as 01111110. The mantissa 1, 0 removes the integer part 0, and fills 0 to 23 digits 00000000 00000000 0000000

    • So the final binary representation is: 0 01111110 00000000 00000000 0000000

    • The second case: E is all 1

    • At this time, if the effective number M is all 0, it means +-infinity (positive or negative depends on S).

    • The third case: E is all 0

      • At this time, the exponent E of the floating-point number is equal to 1-127 (or 1023), and the real value is obtained. The effective number M is no longer added to 1, but restored to the decimal form of 0.xxxxxxx. This is done to represent plus or minus 0, and numbers close to 0.

        • Of course, we also need to know why 1 is no longer added. The real value should be -127, and the floating point number can be expressed as (-1)^S*2^(-127)*1.xxxxxxxx. This number is close to 0. At this time, we have this rule, and we will no longer add 1 before the effective number M


After understanding the rules of playing IEEE 754, back to our original question, why is 0x00000009 converted to a floating point number and becomes 0.000000? ? ? First split 0x00000009 to get the first symbol s=0, the index E=00000000 of the next 8 digits, and the effective digits of the last 23 digits are 000 0000 00000000 00001001

int main()
{
	int n = 9;
	//9->     0 0000000 0000 0000 0000 0000 0000 1001
	//由于E为全0,所以符合第三种情况。
	//因此浮点数可以表示为V= (-1)^0*0.00000000000000000001001*2*(-126)=1.001*2^(-146)
	//很明显V是一个接近于0的数,所以结果表示为0.000000
	float* pFloat = (float*)&n;
	printf("n的值为:%d\n", n);
	printf("*pFloat的值为:%f\n", *pFloat);
	*pFloat = 9.0;
	//9.0->   1001.0		可以表示为(-1)^0*1.0010*2^3  所以S=0,M=1.0010  E=3
	//我们还原成二进制就是 0 10000010 001 0000  0000 0000 0000 0000
	//这个二级制换成十进制就是  1091567616
	printf("num的值为:%d\n", n);
	printf("*pFloat的值为:%f\n", *pFloat);
	return 0;
}

Finally, we use the computer to verify:

 

Finally: I hope this article gives you a new understanding of the storage of floating-point numbers, and I will update it from time to time to share my learning experience. 

Guess you like

Origin blog.csdn.net/m0_72165281/article/details/131015125