C语言强制类型转换

C语言强制类型转换又因为 float 类型的位数部分只有 23bits 故多余部分会被舍弃 只保留 23 位 第 24 位为 1 进 1 否则舍去

大家好,欢迎来到IT知识分享网。

目录

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)

0 1000 0010

010 1000 0000 0000 0000 0000

  十六进制:0x

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

                                  

0 100 0000 0010

0101  00000000 00000000 00000000 00000000 00000000 00000000

  十六进制:0x 00000000

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

33efc34a2cc64c9f95a543fa147b6c6f.png

 用VS,验证变量b的内存存储情况正好为0x 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被解释为整数,即

    0000000000B = D

 

4fea6ffc512a4fda904b9458a789b7a3.png

 

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

 

2.2.变量类型强转

(1).int —>float

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

 

整型 的二进制补码为

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

转化为十进制为.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

 

 

 

 

 

 

 

 

 

 

 

 

 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/125105.html

(0)
上一篇 2025-09-30 16:10
下一篇 2025-09-30 16:15

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信