在C中将int打印为float

bug*_*ger 7 c printf

我正在为Little Endian使用Visual Studio TC编译器.以下是这段代码:

void main()
{    
    float c = 1.0;
    int a = 0x3F800000;
    int *ptr = (int *)&c;
    printf("\n0x%X\n", *ptr);
    printf("\na = %f", a);
    printf("\nc = %f", c);
    return;    
}
Run Code Online (Sandbox Code Playgroud)

输出是:

0x3F800000
a = 0.000000
c = 1.000000
Run Code Online (Sandbox Code Playgroud)

浮点值1.0为0x3F800000,并在内存中存储为00 00 80 3F,适用于Little Endian.将相同的值分配给int a.printf如何打印0.000000一段时间1.000000 for float c?我已经看到它在printf中使用%f打印时将所有整数值打印为0.000000.

另外,由于printf是可变参数函数,它如何知道寄存器中传递的值是int还是float?

Med*_*noc 6

我的通灵能力告诉我Adam Liss的评论是正确的答案:float参数被提升为double,所以printf()函数期望发生:它期望堆栈上的64位值,但得到32位加上碰巧为零的垃圾数据.

如果提高显示精度,显示应该是这样的a = 0.00000000001.

这也意味着这应该工作:

void main()
{    
    double c = 1.0;
    long long a = 0x3FF0000000000000;
    long long *ptr = (long long *)&c;
    printf("\n0x%llX\n", *ptr);
    printf("\na = %f", a);
    printf("\nc = %f", c);
    return;    
}
Run Code Online (Sandbox Code Playgroud)


V-X*_*V-X 5

我已经用gcc编译了你的代码,生成的代码如下:

movl    $0x3f800000, %eax
movl    %eax, -4(%ebp)
movl    $1065353216, -8(%ebp)
leal    -4(%ebp), %eax
movl    %eax, -12(%ebp)
movl    -12(%ebp), %eax
movl    (%eax), %eax
movl    %eax, 4(%esp)
movl    $LC1, (%esp)
call    _printf
movl    -8(%ebp), %eax
movl    %eax, 4(%esp)
movl    $LC2, (%esp)
call    _printf
flds    -4(%ebp)
fstpl   4(%esp)
movl    $LC3, (%esp)
call    _printf
Run Code Online (Sandbox Code Playgroud)

这可能会给你一个提示,浮动参数不是从常规堆栈中获取而是从浮点堆栈中获取...我希望会有一些随机而不是0 ...


Bor*_*ort 5

正如-Wall所述: warning: format ‘%f’ expects type ‘double’, but argument 2 has type ‘int’。这是未定义的行为,这里也有更详细的解释。

如果转换规范无效,则行为未定义。如果任何参数不是相应覆盖规范的正确类型,则行为未定义。

所以你在这里看到的是编译器构建器决定发生的事情,可以是任何事情。