整形,浮点数变量数据全解读

目录

整数数据储存方式

浮点型数字储存方式


整数数据储存方式

           在了解数据储存方式之前,我们需要分清楚数据类型的基本归类,真篇文章种主要研究的类型为整形家族,浮点型家族。

            整形家族主要包括 char shor int long 与及他们各自的unsigned 。

           整形数据的储存简单的说就是将每个数据的补码储存进内存中进行运算。

           原码
                直接将数值按照正负数的形式翻译成二进制就可以得到原码。
           反码
                将原码的符号位不变,其他位依次按位取反就可以得到反码。
           补码
                反码+1就得到补码。

               大小端:

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

                同时还需要强调一下每个类型的字节数: char-1 short-2  int-8  long 和 long long 则是根据不同的编译器又不一样的位数。 

%u 打印负值

        看一下代码,思考得出的答案

int main()
{
	int a = -128;
	printf("%d %u\n", a,a);
	return 0;
}

 首先a是int 类型,是一个四位的二进制数,一位八个字节,就是32个字节,-128用二进制补码表示为 11111111 11111111 11111111 00000000,易知a中储存的数据便是如此,如果是用%d打印则表示可以看做打印时默认最高位1表示-(2^31),其余均为正数,也就是可以用这个方式计算%d要打印数字的大小,而%u打印则将最高位也看作正数,因此会得到一个很大的数,结果如下:

-128    4294967168

而将unsigned变量赋为复数也与上述过程相同,赋值的时候

 unsigned 变量赋负值

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

 char型变量在内存中占一个字节,也就是八位故-1的补码为1111 1111 %d打印signed类型的变量则会自动计算出次补码所对应的值,而%d打印unsigned 的值则是不为补码,直接是没有符号位的二进制数字,此时计算后对于的十进制数字为255,故c打印出来的为255

越界,截断,整形扩展

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

char有符号表示的范围为-128——127,故此时将a 赋为128发生了越界,128对于的二进制补码为    1000 0000 而printf中%u接受的int类型的数字,因此需要进行整形扩展,由于是有符号数,扩展时高位补符号位,%u接收到的为11111111 11111111 11111111 10000000此补码对应的十进制数为-128,因此打印出来的为128.

同时这题还有另一个理解方式,就是补码的技术为0->....->127->-128->-127->....->0

而128可以看成127+1,此时对应的数就是-128。

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

这个函数乍一看可能没什么问题,但是实际上有着很大的问题,首先我们要明白,for循环的流程是先进行i--再进行i>=0的判断,因此在i=0的时候进入for循环时,先进行i--,i内存中储存的数有00000000 00000000 00000000变为 11111111 11111111 11111111 如果是有符号数,则此时i会变为-1 for循环终止,而此时为无符号数,则对应的会变为

16777215,此时再进行i--一路减到0之后再回到16777215,故为死循环。

浮点型数字储存方式

                单精度浮点数储存方式:

 S表示符号位,E为阶数,M是尾数,每个数字都可以写成:(-1)*s*1.M*2^(E+127)

这里对E加上127是为了使E可以表示出复数,因此我们可以看出,如果E全为0在单精度浮点型中表示的便是-127,全一则表示128,故一个非常小一个非常大,所以一个为0,另一个为无穷,

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

 

 我们对以上程序进行分析,n赋为9时会有00000000 00000000 00001001  而通过以上浮点数的分析,知道如果将其看成浮点数时,E全为0,此时解读为0,而对其赋值成9.0,则表示为1001->1.001*2^3,为0 10000010 00100000000000000000000 

故将其解读为int时会是一个非常大的数 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值