You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过memcpy将int按位转为float结果为0,求原因解析

Why does memcpy-ing an int value 0x7fffff to a float result in 0.000000?

I'm trying to create a float by directly setting its binary bits, and I learned memcpy is a good approach for this. I wrote the following code:

#include <stdio.h>
#include <string.h>

float i2f(int i) {
    float result;
    memcpy(&result, &i, sizeof(int));
    return result;
}

int main() {
    printf("Size of int is %d.\n", sizeof(int));
    printf("Size of float is %d.\n", sizeof(float));
    int i = 0x7fffff;
    float f = i2f(i);
    printf("int value is %d.\n", i);
    printf("float value is %f.\n", f);
    return 0;
}

When I run it, the output is:

Size of int is 4.
Size of float is 4.
int value is 8388607.
float value is 0.000000.

Why am I getting 0.0 for the float value?


Let's break this down step by step to understand what's happening:

1. First, recall 32-bit IEEE 754 float structure

A single-precision float uses 32 bits split into three parts:

  • 1 sign bit (0 = positive, 1 = negative)
  • 8 exponent bits (with a fixed bias of 127)
  • 23 mantissa (fraction) bits (with an implicit leading 1 for normal numbers)

2. Analyze the bit pattern of your int

Your int 0x7fffff is equal to 8388607, which in binary is 23 consecutive 1s. When stored as a 32-bit int, the full bit pattern is:
00000000 11111111 11111111 11111111

When you memcpy this into a float, we're interpreting this exact bit pattern as an IEEE 754 float.

3. Interpret the bit pattern as a float

Breaking down the bits for the float:

  • Sign bit: 0 (positive value)
  • Exponent bits: The first 8 bits after the sign are 00000000
  • Mantissa bits: The remaining 23 bits are all 1s

In IEEE 754, an exponent of all 0s means this is a denormalized (subnormal) number. For denormals:

  • We use an implicit leading 0 instead of the usual 1
  • The effective exponent is 1 - 127 = -126 (instead of exponent_value - 127)

Calculating the actual value:

value = (-1)^sign * (0.mantissa) * 2^(effective_exponent)
value = 1 * (0.111...111) * 2^-126

This equals approximately 1.175494e-38—an extremely small number.

4. Why %f shows 0.000000

The %f format specifier by default displays 6 decimal places. Since 1.175494e-38 is way smaller than 0.000001 (the smallest non-zero value that shows up with 6 decimal places), it gets rounded to 0.000000 when printed with %f.

5. Verify the actual value

If you use a format specifier that handles very small numbers, like %e (scientific notation) or %g, you'll see the real value. Try changing your printf line to:

printf("float value is %e.\n", f);

You'll get output like 1.175494e-38, which confirms the float isn't actually zero—it's just too small to show up with the default %f formatting.


内容的提问来源于stack exchange,提问作者zzz_zzz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:54:18