这个程序主要通过以下方式展示浮点数在内存中的二进制存储:
核心原理:
使用reinterpret_cast获取浮点数在内存中的原始字节表示
将每个字节转换为 8 位二进制字符串
按照 IEEE 754 标准格式解析二进制数据
IEEE 754 浮点数格式:
单精度 (float):32 位,1 位符号位 + 8 位指数位 + 23 位尾数位,指数偏移量为 127
双精度 (double):64 位,1 位符号位 + 11 位指数位 + 52 位尾数位,指数偏移量为 1023
主要函数:
toBinaryString:模板函数,将任意类型的数据转换为二进制字符串
displayFloatBinary:展示 float 类型的二进制存储结构
displayDoubleBinary:展示 double 类型的二进制存储结构
数值表示方式:
浮点数在内存中以科学计数法形式存储:(-1)^符号位 × (1.尾数位) × 2^(指数位-偏移量)
[C++] 纯文本查看 复制代码 #include <iostream>
#include <bitset>
#include <iomanip>
using namespace std;
// 函数模板:将任意类型的数据转换为二进制字符串
template <typename T>
string toBinaryString(const T& value) {
string binary;
const char* bytes = reinterpret_cast<const char*>(&value);
// 从最高有效字节到最低有效字节
for (size_t i = 0; i < sizeof(T); ++i) {
// 使用bitset将每个字节转换为8位二进制
bitset<8> byteBits(bytes[sizeof(T) - 1 - i]);
binary += byteBits.to_string();
}
return binary;
}
// 展示float类型的二进制存储(32位)
void displayFloatBinary(float f) {
cout << "float类型 (" << fixed << setprecision(6) << f << ") 在内存中的二进制表示:" << endl;
// 获取32位二进制字符串
string binary = toBinaryString(f);
// IEEE 754单精度浮点数格式:1位符号位,8位指数位,23位尾数位
string signBit = binary.substr(0, 1);
string exponentBits = binary.substr(1, 8);
string mantissaBits = binary.substr(9, 23);
cout << "符号位: " << signBit << " (0表示正,1表示负)" << endl;
cout << "指数位: " << exponentBits << " (偏移量为127)" << endl;
cout << "尾数位: " << mantissaBits << endl;
cout << "完整表示: " << signBit << " " << exponentBits << " " << mantissaBits << endl << endl;
// 计算实际指数值(指数位 - 偏移量)
bitset<8> exponent(exponentBits);
int exponentValue = static_cast<int>(exponent.to_ulong()) - 127;
cout << "计算得到的指数值: " << exponentValue << endl;
cout << "数值表示: (-1)^" << signBit << " × (1." << mantissaBits << ") × 2^" << exponentValue << endl << endl;
}
// 展示double类型的二进制存储(64位)
void displayDoubleBinary(double d) {
cout << "double类型 (" << fixed << setprecision(12) << d << ") 在内存中的二进制表示:" << endl;
// 获取64位二进制字符串
string binary = toBinaryString(d);
// IEEE 754双精度浮点数格式:1位符号位,11位指数位,52位尾数位
string signBit = binary.substr(0, 1);
string exponentBits = binary.substr(1, 11);
string mantissaBits = binary.substr(12, 52);
cout << "符号位: " << signBit << " (0表示正,1表示负)" << endl;
cout << "指数位: " << exponentBits << " (偏移量为1023)" << endl;
cout << "尾数位: " << mantissaBits << endl;
cout << "完整表示: " << signBit << " " << exponentBits << " " << mantissaBits << endl << endl;
// 计算实际指数值(指数位 - 偏移量)
bitset<11> exponent(exponentBits);
int exponentValue = static_cast<int>(exponent.to_ulong()) - 1023;
cout << "计算得到的指数值: " << exponentValue << endl;
cout << "数值表示: (-1)^" << signBit << " × (1." << mantissaBits << ") × 2^" << exponentValue << endl << endl;
}
int main() {
// 测试几个典型的浮点数
cout << "=== 测试1:正整数 ===" << endl;
float f1 = 123.0f;
displayFloatBinary(f1);
cout << "=== 测试2:负小数 ===" << endl;
float f2 = -3.14159f;
displayFloatBinary(f2);
cout << "=== 测试3:双精度浮点数 ===" << endl;
double d1 = 0.1;
displayDoubleBinary(d1);
cout << "=== 测试4:特殊值 ===" << endl;
float f3 = 0.0f;
displayFloatBinary(f3);
float f4 = 1.0f / 0.0f; // 正无穷大
displayFloatBinary(f4);
return 0;
}
|