整形和浮点型数据存储详解

一、整形数据在内存中的存储

1.原码,反码,补码介绍

计算机中的数据都是以二进制补码的形式进行储存的。
正数: 原码=反码=补码
负数:
原码:最高位是符号位,其他位变为对应二进制。
反码:原码符号位不变,其他位按位取反。
补码:反码加1.

2.例题详解

2.1 此段代码的输出结果是?

#include<stdio.h>
#include<windows.h>
int main(){
    
    
	char a = -1;
	signed char b = -1;
	unsigned char c = -1;
	printf("a=%d\nb=%d\nc=%d\n", a, b, c);
	system("pause");
	return 0;
}

首先得到char-1的二进制补码为1111 1111
所以我们得知计算机已经把这个二进制序列存入了内存中,现在我们要根据输出类型去取这个二进制序列。
因为输出的是整形,所以要发生整形提升,比特位由8位变为32位,整形提升看自身类型,有符号数补最高位的数字,无符号数补0
由题意得a,b为有符号数,并且最高位为1所以补一,他的二进制补码序列变为 1111 1111 1111 1111 1111 1111 1111 1111 我们再进行按位取反和加一操作得到我们的结果 1000 0000 0000 0000 0000 0000 0000 0001所以a和b都是-1
c就比较有意思了,因为他是无符号数,所以他要补0,则他的二进制补码为 02 0000 0000 0000 0000 0000 0000 1111 1111 因为我们是整形打印,所以我们看最高位是0他的补码就是原码,所以c=255。

请添加图片描述

2.2 此段代码的输出结果是?

#include<stdio.h>
#include<windows.h>
int main(){
    
    
	char a = -128;
	printf("a=%u", a);
	system("pause");
	return 0;
}

-128原码 [10000000][00000000][0000000][10000000]
-128补码[11111111][11111111][1111111][10000000]
因为要存储在char类型中,所以要发生截断,只能存1000 0000
输出的时候因为输出的是%u所以要进行整形提升整形提升看自身类型,他是一个有符号char型,所以补符号位1,形成新的二进制补码序列1111 1111 1111 1111 1111 1111 1000 0000 输出的时候以%u输出,为无符号类型,所以此时的补码就是最终的结果所对应的二进制。
在这里插入图片描述

在这里插入图片描述

二、浮点型数据在内存中的存储

1.浮点数的存储方式

任意一个二进制浮点数可以表示成下面的形式
(-1) ^ S * M *2^ E
(-1) ^ S表示符号位,当s=0时候表示正数,当s=1表示负数
M表示有效数字
2^ E表示指数位

例如5.0的存储方式为:

请添加图片描述
在计算机保存M的时候,默认这个数字的第一位总是1,所以一般都会暂时舍弃,保存小数点后面的数字,等到取出来的时候再把1加上。例如存1.011的时候只存011。
E是一个无符号整数,但是指数有时候可以为负数,所以我们规定在存的时候要先给他加一个中间数,若E是8位则加上127,若E为11位则加上1023。然后E从内存中取出的时候分为两种情特殊况。
**E全为0:**则指数的有效值为0-127=-127。这时原来的数字是一个接近0的数字了。
E全为1:则指数为255 ,则原来的数字就是一个非常大的数字了。

2. 例题解析:


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

第一条结果肯定是9,没什么好说的。
第二条输出的时候是以%f对内存中9的二进制进行输出的,所以适用我们浮点数输出的准侧,9的二进制为00000000000000000000000000001001我们发现E全为0,所以他的结果便全是0。

在这里插入图片描述

#include<stdio.h>
#include<windows.h>
int main(){
    
    
	int n = 9;
	float * pFloat = (float*)&n;
	*pFloat = 9;
	printf("n的值为%d\n", n);//大数字
	printf("*pFloat的值为%f\n", *pFloat);//9.0000
	system("pause");
	return 0;
}

*pFloat=9赋值语句左边是浮点型,右边是整形,再赋值之前要发生隐式转换,由整形变为浮点型,然后将浮点型9的二进制保存在内存中,浮点型9的二进制是 0 10000010 00100000000000000000000 输出的时候是以%d的形式输出的,又因为最高位是0所以输出的结果就是这个二进制序列,最终的结果是
在这里插入图片描述

在这里插入图片描述

Guess you like

Origin blog.csdn.net/weixin_50302770/article/details/120661656