1.整形和浮点型在计算机中的存储

源码,反码,补码的转化

首先我们要知道,一个字节有8个比特位。
对于正数而言他的三种码都是一样的
而对于负数来说

在这里插入图片描述
补充:short和char类似,这俩都分为short;signed short;unsigned short.
short = signed short = signed short [int].

大小端存储

大端(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;
小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地址中。


检测大端还是小端的代码:
int main()
{
	int i = 1;
	char p = (char)i;//因为如果int转换成char会存在截断的问题.
	if (p == 1)
	{
		printf("小端");
	}
	if (p == 0)
	{
		printf("大端");
	}

	system("pause");
	return 0;
}

//方法2
union un {
	int i;
	char c;
};
int main()
{
	union un u;
	u.i = 1;
	printf("%d", u.c);
	system("pause");
	return 0;
}

例题1:

	char a= -1;
    signed char b=-1;
    unsigned char c=-1;
    printf("a=%d,b=%d,c=%d",a,b,c);
    return 0;

思路:有符号的char存储先源码,最后转化成补码存储.所以
源码:10000001;反码:11111110;补码:11111111.又因为以%d输出(有符号的整形)所以又要从补码变回源码,又是-1.
而无符号的char直接把源码当做补码:10000001存储,所以以%d输出的时候,又会把10000001当做补码转换成源码,10000000,11111111.所以结果为255.
截断:发生在大转小
提升:发生在小转大;符号位为1补1,符号位为0补0;

例题2:

 char a = -128;
    printf("%u\n",a);
    return 0;
    

思路:截断
0x 10000000 00000000 00000000 10000000
0x 11111111 11111111 11111111 01111111
0x 11111111 11111111 11111111 10000000
a截断->10000000
然后%u是无符号的所以直接输出

例题3

 char a = 128;
    printf("%u\n",a);
    return 0;

思路:同理2,结果一样.都是一个比较大的值

例4:

unsigned int i;
    for (i = 9; i >= 0; i--)
    {
         printf("%u\n", i);
    }

分析:
当运行到i=-1

但由于i是无符号数,所以最高位不表示符号位,最高位也是数值位即(2^32-1)大于0,陷入死循环

例5:

unsigned char i = 0;
    for (i = 0; i <= 255; i++)
    {
        puts("hello world!\n");
    }

unsigned char 取值范围为0 -255,无论如何i的值都在0 - 255之间,所以会陷入死循环

浮点型在内存中的存储

切记浮点数在内存中的存储是不同于整形的!
规则:
在这里插入图片描述

比如十进制的5.0,二进制就是0101.0 就可以写成(-1)^ 0 * 1.01 * 2 ^ 2
在比如十进制的-5.0,二进制就是-0101.0 就可以写成(-1)^ 1 * 1.01 * 2 ^ 2
而规定float类型有一个符号位(S),有8个指数位(E),和23个有效数字位(M)
double类型有一个符号位(S),有11个指数位(E),和52个有效数字位(M)

在这里插入图片描述
E在存储的时候都是正数,又因为E是8比特位,和char类似,所以为了保证他在存寄进去的时候一定是正的,要给E加127(在取的时候再减127就好了).

例:

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

在这里插入图片描述
以整形存以整形取,或者以浮点存以浮点取都不会发生错误。但是如果整形和浮点型的类型就会出现变化

首先解释第一个。因为9是以整形存储以浮点数输出。相当于浮点数的提取。
整形的9在内存中以补码存储的(正数三码相同)。9——>0000 0000 0000 00001001
,而在提取的时候对于E还分为三种情况:
E不全为0,不全为1:
这时就用正常的计算规则,E的真实值就是E的字面值减去127(中间值),M的值要加上最前面的省去的1。
E全为0
这时指数E等于1-127为真实值,M不在加上舍去的1,而是还原为0.xxxxxxxx小数。这样为了表示0,和一些很小的整数。
E全为1
M全为0时,表示±无穷大(取决于符号位),M不全为1时,表示这数不是一个数

此时E为全0,所以符合第二种,M不加1,E在提取的时候减去127.
所以v=(-1)^0 * 0.0000000000001001 * 2^(-127)这是一个很小的数,所以相当于0.

接下的解释第二种。9以浮点数的形式存储。所以9.0=1001.0
所以s=0,E=3+127=130,M=1.001
浮点数9.0在内存中的二进制位:0 10000010 001 00000000000000000

(130的二进制位10000010,补在E位置,M为1.001,把最前面的1去掉,剩下0.001放在M位置),此时把这个二进制以补码的形式拿出来就是一个很大的值。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值