代码改变世界

深入解析:C语言中的浮点数与整数的存储方式

2025-09-29 21:24  tlnshuju  阅读(40)  评论(0)    收藏  举报

在 C 语言中,​​浮点数(float、double、long double)​​ 和 ​​整数(int、short、long、long long 等)​​ 是两种不同类型的数据,它们在计算机内部的 ​​存储方式、表示方法、精度和用途​​ 都有显著区别。下面我们将分别详细介绍它们的存储方式。

一、整数的存储方式

1. 整数的表示

整数在计算机中是以 ​​二进制补码(Two's Complement)​​ 的形式存储的(对于有符号整数),无符号整数直接以二进制原码形式存储。

有符号整数(如 int, short, long)

  • 最高位为符号位:​​
    • 0表示正数或零
    • 1表示负数
  • 正数:​​ 直接是其二进制表示。
  • 负数:​​ 使用 ​​补码(Two’s Complement)​​ 表示:
    • 补码 = 反码 + 1
    • 反码 = 原码按位取反(符号位不变)

例如:

十进制原码补码
50000010100000101
-51000010111111011

无符号整数(如 unsigned int)

  • 所有位都用于表示数值,没有符号位。
  • 范围是从 0 到 2^n - 1(n 是位数)

2.存储细节

整数在内存中按照 ​二进制补码形式从低位到高位依次存储​​,存储顺序还与系统的 ​字节序(大端/小端)​ 有关:

  • ​小端序(Little Endian,x86/x64 平台常见):低字节存放在低地址​
  • ​大端序(Big Endian,某些网络设备和旧系统):高字节存放在低地址​

例如,32 位整数0x12345678在内存中的存储(小端):

低地址 -> 高地址:0x78 0x56 0x34 0x12

二、浮点数存储方式

1. 浮点数的表示标准:IEEE 754

C 语言中的浮点数类型(如 float, double,long double)通常遵循 ​IEEE 754 浮点数标准​ 来存储。最常用的是:

  • float(单精度浮点数):​​ 32 位
  • ​​double(双精度浮点数):​​ 64 位
  • ​​long double(扩展精度,具体位数平台相关,可能是 80 位、96 位 或 128 位)​

这里主要介绍两种最常用的,float和double。

1.1. float(32位)的 IEEE 754 格式

组成部分

位数

描述

Sign

1

符号位:0 表示正数,1 表示负数

Exponent

8

指数部分(带偏移,偏移量是 127)

Fraction(Mantissa)

23

尾数(有效数字,隐含前导 1)

公式:(-1)^sign × 1.M × 2^(exponent - 127)

  • 1.M​​:尾数部分前面默认有一个隐藏的 "1."(规格化数),即实际有效位是 24 位(1 + 23)​
  • exponent - 127​:称为 ​偏移表示法(bias)让指数可以为正也可以为负就是​,目的

特殊情况:​​

  • 若 exponent 全为 0: 表示 ​​非规格化数(denormalized)​​ 或 ​​零​​
  • 若 exponent 全为 1:
    • 若 fraction 全为 0:表示 ​​正负无穷(±Infinity)​​
    • 若 fraction 非 0:表示 ​​NaN(Not a Number)​

1.2. double(64位)的 IEEE 754 格式

组成部分

位数

描述

Sign

1

符号位

Exponent

11

指数部分,偏移量为 1023

Fraction

52

尾数部分,隐含前导 1

公式:(-1)^sign × 1.M × 2^(exponent - 1023)

同样有非规格化数、无穷大、NaN 等特殊值处理

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

例如:float a = 12.5;

  1. 首先将其转化为二进制:1100.1
  2. 规格化:1.1001 × 2^3
  3. 得到:
    • fraction(尾数)= 10010000000000000000000(23位,后面补零)
    • exponent = 3 + 127 = 130 → 二进制 10000010
    • sign = 0(正数)
  4. 组合:
    1. Sign: 0
    2. Exponent: 10000010
    3. Fraction: 10010000000000000000000

16进制0x41480000。就是因此,最终 32 位 float 表示为:0 10000010 10010000000000000000000,也就

根据这个逻辑,我们发现浮点数无法精确存储,比如0.1,他在二进制中是一个无限循环的小数。

在进行存储时,一但超出固定尾数范围就会出现舍入误差。

三、总结

特性

整数(int, long等)

浮点数(float, double)

表示内容

整数值(正、负或零)

带小数部分的实数(可能有精度损失)

存储格式

二进制原码或补码

IEEE 754 标准(符号、指数、尾数)

是否有精度困难

有(特别是小数,如 0.1 无法精确表示)

比较操作

直接比较是否相等

不可直接比较是否相等,应考虑误差范围

典型用途

计数、索引、离散值

科学计算、测量值、图形坐标等连续值

常见类型(32位系统)

int(32位)、long(32/64位)

float(32位)、double(64位)

内存占用(典型)

int:4 字节,long:4/8 字节

float:4 字节,double:8 字节

否相等时,需设置误差就是备注:在比较两个浮点数