详细介绍float, double, long double类型的基本结构

书籍:《ISO/IEC 14882 2014》

说明:以上内容大部分来自腾讯元宝

在C++中,floatdoublelong double是三种浮点类型,其基本结构遵循IEEE 754标准,但具体实现细节因编译器和平台而异。以下是它们的详细结构解析:


一、​​float(单精度浮点数)​

1. ​​存储结构​
  • ​总位数​​:32位(4字节)
  • ​位域分配​​:
    位域位数描述
    符号位(S)10表示正数,1表示负数
    指数位(E)8采用偏移量127的移码表示(实际指数值 = 存储值 - 127
    尾数位(M)23存储小数部分的二进制展开(隐含前导1,实际有效位数为24位
2. ​​数值范围与精度​
  • ​范围​​:±1.4×10⁻⁴⁵ ~ ±3.4×10³⁸
  • ​精度​​:约6-7位十进制有效数字
  • ​示例​​:
    3.14159f 在内存中表示为:
    0 10000000 10010001111010111000011(符号位0,指数128-127=1,尾数1.10010001111010111000011)

二、​​double(双精度浮点数)​

1. ​​存储结构​
  • ​总位数​​:64位(8字节)
  • ​位域分配​​:
    位域位数描述
    符号位(S)1同上
    指数位(E)11偏移量1023(实际指数值 = 存储值 - 1023
    尾数位(M)52隐含前导1,实际有效位数为53位
2. ​​数值范围与精度​
  • ​范围​​:±4.9×10⁻³²⁴ ~ ±1.8×10³⁰⁸
  • ​精度​​:约15-16位十进制有效数字
  • ​示例​​:
    3.141592653589793 在内存中表示为:
    0 10000000000100100 111101011100001100110100010001000010110100011

三、​​long double(扩展精度浮点数)​

1. ​​存储结构​
  • ​总位数​​:平台依赖(常见为80位或128位)
    • ​x86架构​​:80位(10字节),但通常以16字节(128位)对齐存储。
    • ​GCC/Clang​​:可能支持80位扩展精度(__float128)。
  • ​位域分配​​(以80位为例):
    位域位数描述
    符号位(S)1同上
    指数位(E)15偏移量16383(实际指数值 = 存储值 - 16383
    尾数位(M)64隐含前导1,实际有效位数为65位
2. ​​数值范围与精度​
  • ​范围​​:±3.4×10⁻⁴⁹³² ~ ±1.1×10⁴⁹³²
  • ​精度​​:约18-19位十进制有效数字
  • ​示例​​(80位格式):
    3.14159265358979323846 可能存储为:
    0 1000011111110000 111101011100001100110100010001000010110100011000000000

四、​​关键差异对比​

​属性​​float​​double​​long double​
​存储空间​4字节8字节8/16字节(平台依赖)
​符号位​1位1位1位
​指数位​8位(偏移127)11位(偏移1023)15位(偏移16383)
​尾数位​23位(隐含1)52位(隐含1)64位(隐含1)
​有效位数​6-7位十进制15-16位十进制18-19位十进制
​典型用途​内存敏感场景通用科学计算高精度数学运算

五、​​内存布局示例​

1. ​​float示例​​:1.5f
  • ​二进制科学计数法​​:1.1 × 2¹
  • ​存储值​​:
    • 符号位:0
    • 指数位:10000000(128,实际指数128-127=1)
    • 尾数位:10000000000000000000000(隐含前导1后为1.1
2. ​​double示例​​:√2 ≈ 1.4142135623730951
  • ​二进制科学计数法​​:1.0110101000001001111001100110011111111010
  • ​存储值​​:
    • 符号位:0
    • 指数位:1000000000001011(1024 + 11 = 1035,实际指数1035-1023=12)
    • 尾数位:0110101000001001111001100110011111111010(隐含前导1)

六、​​特殊值表示​

​值类型​​符号位(S)​​指数位(E)​​尾数位(M)​
​正零​0全0全0
​负零​1全0全0
​正无穷大​0全1全0
​NaN​0/1全1非全0

七、​​跨平台注意事项​

  1. long double的差异​​:
    • MSVC中与double同为8字节,GCC/Clang可能支持80位扩展精度。
  2. ​对齐问题​​:
    • 结构体中包含long double时,可能因对齐导致内存浪费(如填充字节)。
  3. ​输出控制​​:
    • 使用<iomanip>库的setprecisionfixed确保跨平台一致性。

八、​​代码验证​

#include <iostream>
#include <iomanip>

int main() {
    std::cout << std::boolalpha;
    std::cout << "float size: " << sizeof(float) << " bytes\n";
    std::cout << "double size: " << sizeof(double) << " bytes\n";
    std::cout << "long double size: " << sizeof(long double) << " bytes\n";

    // 输出内存布局(以float为例)
    float f = -123.456f;
    unsigned int* p = reinterpret_cast<unsigned int*>(&f);
    std::cout << "float binary: " << std::hex << *p << std::dec << "\n";

    return 0;
}

​输出示例​​:

float size: 4 bytes
double size: 8 bytes
long double size: 16 bytes
float binary: 42f6e979

总结

  • ​float​​:适合内存敏感场景,但精度有限。
  • ​double​​:通用选择,平衡精度与性能。
  • ​long double​​:高精度需求场景,但需注意平台兼容性。

通过理解内部结构,可以更好地控制浮点数的精度和存储行为。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值