使用%d格式符输出float值不符合little-endian预期的原因排查
为什么你的代码没输出预期的512?
嘿,这个问题踩了两个很容易忽略的C语言细节坑,咱们慢慢理清楚:
首先,你对float 2.0的二进制存储理解错了
你以为float a=2;在内存里是0x00 00 00 02(小端后变成0x02 00 00 00),这是整数int的存储方式,但float遵循IEEE 754单精度浮点数标准,完全不是这么存的:
- 2.0的二进制是
10,转换成IEEE754单精度格式后,由1位符号位、8位指数位、23位尾数位组成:符号位0(正数),指数位是127+1=128(二进制10000000),尾数位全0 - 对应的32位二进制是:
0 10000000 00000000000000000000000,转换成十六进制就是0x40000000 - 按你说的小端存储,内存里的字节顺序是
0x00 00 00 40(小端模式下,低字节存在低地址,所以把十六进制倒过来拆成字节)
其次,printf的可变参数有类型提升规则
C语言里,可变参数函数(比如printf)接收float类型参数时,会自动把它提升为double类型(double是8字节)。所以你的a实际被转换成了8字节的double值,2.0的double格式IEEE754是0x4000000000000000,小端存储的话,内存里的字节顺序是:0x00 00 00 00 00 00 00 40
最后,%d读取时的实际行为
%d格式符告诉printf要读取一个2字节的int值,但此时参数列表里对应的是8字节的double。printf会从这个参数的起始位置读取前2个字节——也就是0x00 00,转换成十进制就是0,这就是你实际得到的结果(而不是你预想的512)。
另外要提醒一句:这种用不匹配的格式符读取参数的行为属于未定义行为,C标准不保证任何特定结果,不同编译器、平台可能有不同表现,上面的分析只是基于常见的实现逻辑。
内容的提问来源于stack exchange,提问作者Sagar P
相关产品推荐
相关产品推荐

