C语言:整数和浮点数在内存中的存储

C语言整数与浮点数内存存储解析

1.整数在内存中的存储

        众所周知,整数是以二进制的形式储存在计算机中的,但在计算机执行操作整数操作的时候,实际上使用的是整数的补码,而并非我们直观的原码。接下来就先了解一些"码",再讨论整数的储存。

        1.1原码、反码和补码

        原码,就是整数的二进制形式

int类型的9
00000000 00000000 00000000 00001001
int 类型的-15
10000000 00000000 00000000 00001111

        反码,原码除了符号位之外取反

-15的反码
01111111 1111111 1111111 11110000

        补码,反码+1

-15的补码
01111111 1111111 1111111 11110001

        总而言之,补码=原码取反+1。顺带一提,这具有可逆性,即原码=补码取反+1,便于咱们计算我们正常情况下看到的值。

        1.2整数在内存中的储存

        整数在内存中储存的是补码,而正整数的原码、反码、和补码相同,所以进行正整数运算时不需要进行取反加一的操作,但是负整数不一样,需要先计算补码,再进行计算。不过对于无符号数则不用考虑这么多,毕竟无符号数并没有符号位,当做正整数处理即可。

        1.3整型提升

        指在表达式计算时,表达式含有int,则其余字节数小于整型的类型需要把类型提升为int。如下

char a=2,b=-3;
00000010  10000011
进行整型提升,高位补符号位
a
00000000 00000000 00000000 00000010

b
11111111 11111111 11111111 10000011

        如果是提升为unsigned int 类型,则高位补0.

        如果表达式计算的结果最终赋给了一个char类型的变量,那么可能就会出现截断现象,因为char类型只有八个比特位,不能再存储高位的数据。

2.浮点数在内存中的存储

        2.1IEEE754标准

        先来了解一下国际标准的二进制浮点数表现形式:浮点数 V=(-1)^S * M * 2^E

S表示符号位(0为正,1为负),M表示有效数字(M>=1&&M<2),E表示指数.如

十进制的5.0,写成二进制101.0,    十进制的-5.0,写成二进制-101.0
向右移一位,相当于除2,          同理
于是(-1)^0 * 1.01 * 2^2        (-1)^1 * 1.01 * 2^2
由V得S=0,M=1.01,E=2            由V得S=1,M=1.01,E=2

        2.2浮点数在内存中的储存

        根据IEEE 754的规定,

对于32位的浮点数(float),最⾼的1位存储符号位S,接着的8位存储指数E,剩下的23位存储有效数字M

对于64位的浮点数(double),最⾼的1位存储符号位S,接着的11位存储指数E,剩下的52位存储有效数字M

        2.3特别规定

        M可以写成1.xxx的形式,其中xxx为小数部分,于是IEEE 754规定,计算机在保存M的时候,只保存小数位数,舍去了1,等到读取的时候再加上1,使得M可以储存的有效位数多了一位.

        E是一个无符号整数,但实际上,当要存储的数据是一个小于1的值,如0.01,这时候,E取值为负数,所以规定了一个中间数,对于float类型,E的取值范围为0~255,中间数为127;double类型,E的取值范围为0~2047,中间数为1023.以float举例,2^10,其中E是10,那么将会保存为10+127,也就是10001001.

        以上就是c语言中关于整数储存和浮点数储存的相关规则。

在C语言中,由于数据类型的特性,整数浮点数是两个不同的类型,它们存储运算的方式也不同。为了区分这两种类型,你可以按照以下步骤操作: 1. 定义整型变量 (int) 浮点型变量 (float): ```c int intVar = 5; // 整数示例 float floatVar = 3.14; // 浮点数示例 ``` 2. 使用 `typeof` 关键字检查类型(C99及以上版本): ```c if (sizeof(intVar) == sizeof(long)) { printf("intVar is an integer.\n"); } else if (sizeof(floatVar) == sizeof(double)) { printf("floatVar is a floating-point number.\n"); } ``` 这里我们通过比较变量的内存大小来猜测其类型,但这并不是一种可靠的方法,因为C标准并没有强制要求特定的数据类型占据固定的字节数。 3. 直接比较变量值并使用 `isinf()`、`isnan()` 函数(仅适用于浮点数)检测异常情况: ```c #include <math.h> // 包含数学库 if (!isfinite(floatVar)) { printf("floatVar is not a normal floating-point number.\n"); } if (intVar == INT_MAX || intVar == INT_MIN) { // 对于整数,可以检查是否达到边界值 printf("intVar might be an integer overflow or underflow.\n"); } ``` 请注意,上述方法并非精确地判断类型,而是根据常见场景提供了一种简单的鉴别手段。实际编程中,应避免直接依赖于这种类型检测,而应该明确指定处理每种类型的变量。如果需要更严谨的类型检查,建议使用条件编译宏或者静态分析工具。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值