C语言强制类型转换

目录

1.浮点型的存储方式

1.1.浮点型存储方式

1.2.数值计算表达式

1.3.存储详解

2.类型强制转换

2.1.指针类型强转

2.2.变量类型强转


 

 

 

1.浮点型的存储方式

1.1.浮点型存储方式

(1)float类型在内存中的存储方式:

07d836da36d64bdfb979907d303544cd.png

(2)double类型在内存中的存储方式:

b389c5044dce4875be8f5af18e7cc0ec.png

 

1.2.数值计算表达式

eq?X%3D%28-1%29%5E%7BS%7D*M*2%5E%7BE%7D

~ S  为符号位   0表示整数,1表示负

~E   在 32 位浮点型中,指数位阶码是 8 个比特位,则可以表示的指数范围为0~255,但是指数有正数也有负数,为了表示 -126 ~127,则对每次存储的指数值加上偏移值eq?2%5E%7B8-1%7D%20%3D%20127,读取时在自动减去127。这样指数位为127时表示实际指数为0,指数位大于127表示正指数,指数位小于127表示负指数。指数位阶码位全为 1 和全为 0 用作特殊情况,剩下阶码取值从 1254,减去偏移值后得到指数取值从 -126 127

~E   在 64 位浮点型中,指数位阶码是 11个比特位,则可以表示的指数范围为0~2047,但是指数有正数也有负数,为了表示 -1022 ~1023,则对每次存储的指数值加上偏移值eq?2%5E%7B11-1%7D-1%20%3D%201023,读取时在自动减去1023。这样指数位为1023时表示实际指数为0,指数位大于127表示正指数,指数位小于1023表示负指数。指数位阶码位全为 1 和全为 0 用作特殊情况,剩下阶码取值从 1 2046,减去偏移值后得到指数取值从 -10221023

 

 

~M  表示科学记数法中的尾数部分,由于正规化的浮点数小数点前总是[ 1 , 2 ),所以尾数位实际上省略了小数点前的1。例如尾数位值为 1001,则代表实际值为 1.1001。

 

1.3.存储详解

#include<stdio.h>
int main(void)
{
    float a = 10.5;   
    double b = 10.5;
    return 0;
}    

浮点数10.5转换为二进制为1010.1  利用公式转化1010.1  == eq?%28-1%29%5E%7B0%7D*1.0101*2%5E%7B3%7D

故符号位 S = 0,指数位 E == 3,尾数位 M == 0101

float类型存入时指数位时加偏移值127,即存入130 (二进制:1000 0010)

01000 0010

010 1000 0000 0000 0000 0000

 十六进制:0x41280000

double类型存入时指数位时加偏移值1023,即存入1026 (二进制:100 0000 0010)

                                  

0100 0000 0010

0101  00000000 00000000 00000000 00000000 00000000 00000000

 十六进制:0x40250000 00000000

 用VS,验证变量a的内存存储情况正好为0x 41280000

33efc34a2cc64c9f95a543fa147b6c6f.png

 用VS,验证变量b的内存存储情况正好为0x 40250000 00000000

 

 

2.类型强制转换

2.1.指针类型强转

(1)int  ----->  float

#include<stdio.h>
int main(void)
{	
	int a = 10;
	float* f = (float*)&a;
	
    printf("%f",*f);
	return 0;
}

1. 整形数据在内存中以补码的方式存储,变量 a 为整型占4字节,32比特,

    且10的补码为      00000000000000000000000000001010 ,

故10在内存中的存储方式如下图

cade858dd449453dbc04571c3f68f6a9.png

 2.程序只对地址进行了类型转换,内存地址内保存的内容保持不变,仍然为整数10,由于float 类型与int 类型在内存中均占32个字节,所以通过 float *类型指针访问32比特内存恰好是变量a所在的32比特,编译器就会按照 float 类型的存储格式解释内存中的值;

 

fa2f66721e4848e78c3c73257a32d891.png

 此时  S = 0,E = -127, M = 1.000 0000 0000 0000 0000 1010

 故    

  eq?f%20%3D%20%28-1%29%5E0*1.000%200000%200000%200000%200000%201010*2%5E%7B-127%7D%3D0

因此程序输出结果为0.000000

b2304744ea914a43bb85e146c291bd4b.png

 

 (2). float ---> int

#include<stdio.h>
int main(void)
{
	float a = 10.5;
	int* p = (int*)&a;

	printf("%d", *p);
	return 0;
}

 a 在内存中存储结构如下图:

 ea03b20d3f014988a139999c8b902a3d.png

 

 通过int * 类型指针访问变量a所在的32比特,编译器就会按照int 类型的存储格式解释内存中的值;

因为符号位为0,所以这32bits被解释为整数,即

    01000001001010000000000000000000B = 1093140480D

 

4fea6ffc512a4fda904b9458a789b7a3.png

 

 经过vs环境运行,结果与上文分析一致

 

2.2.变量类型强转

(1).int --->float

#include<stdio.h>
int main(void)
{
	int a = 1234567890;			
	float f = (float)a;
	printf("%f", f);
	return 0;
}

 

整型1234567890 的二进制补码为

de2a65ebac51407da3bc5e1652ab712a.png

 将int 类型 转换成 float 类型即将a的补码当作浮点数存入内存,如下图

b1a370be714b42eb8f90401534916f00.png

此时           eq?X%3D%20%28-1%29%5E%7B0%7D*1.00100110010110000000101101001*2%5E%7B30%7D

 S= 0,E= 30 ,M= 1.00100110010110000000101101001

又因为float类型的位数部分只有23bits,故多余部分会被舍弃,只保留23位,第24位为1进1,否则舍去。得到 M =  1.001 0011 0010 1100 0000 0110

S,E,M,按规则存入内存

f61f8a1f91064ce48da1f7409e20f0e1.png

 

当float类型数据输出时,得到S= 0,E= 157-127=30,M = 1.001 0011 0010 1100 0000 0110

eq?X%3D%20%28-1%29%5E%7B0%7D*1.00100110010110000000110*2%5E%7B30%7D%20%3D%201001%200011%200010%201100%200000%200110%200000%20000

转化为十进制为1234567936.000000

5660d4fba937424d93093d7e6d82aceb.png

 经过vs运行检验,与理论数据一致

(1).float ---> int

#include<stdio.h>
int main(void)
{
	float a = 12.5;
	int b = (int)a;

	printf("%d", b);
	return 0;
}

由前面内容可计算出12.5 在内存中的存储为

 

        cb60718d9bf64749841b40aeec014121.png

 

强转为int 时将其从内从取出:1010.1 去掉小数部分,将整数部分(1010)存入int型内存单元

d79be33c1cc24551821077e5e2771754.png

 故通过%d输出时输出为12

c011cff94b5f41658778b38765d958dc.png

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 11
    点赞
  • 78
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值