C 不能打印/表示非规范化浮点数吗?

Ank*_*wal 1 c floating-point

 $ gcc --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 12.0.5 (clang-1205.0.22.9)
Target: x86_64-apple-darwin20.3.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
$ uname -a
Darwin MacBook-Air.local 20.3.0 Darwin Kernel Version 20.3.0: Thu Jan 21 00:07:06 PST 2021; root:xnu-7195.81.3~1/RELEASE_X86_64 x86_64
Run Code Online (Sandbox Code Playgroud)

代码:

#include <stdio.h>

int main(void) {


    int i = 2;
    printf("int \"2\" as %%.128f:                  %.128f\n", i);

    printf("int \"2\" as %%.128lf:                 %.128lf\n", i);

    printf("int \"2\" as %%.128LF:                 %.128Lf\n", i);

    return 0;

}
Run Code Online (Sandbox Code Playgroud)

编译:

$ gcc floatingpointtypes.c
Run Code Online (Sandbox Code Playgroud)

执行:

$ ./a.out
int "2" as %.128f:                  0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
int "2" as %.128lf:                 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
int "2" as %.128LF:                 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Run Code Online (Sandbox Code Playgroud)

当整数 2 的二进制被解释为 IEEE-754 单精度(32 位)或双精度(64 位)浮点数格式时,它是一个非规范化浮点数(指数位全为 0),十进制的结果值为 2e- 148.

题:

为什么我的代码打印 0s?是因为 C 无法将非规范化浮点数解释为正确的值吗?

Chr*_*odd 5

如果要将 int 的“位”转换为浮点类型,最简单的方法是使用联合:

#include <stdio.h>
#include <stdint.h>

union u32 {
    int32_t     i;
    float       f;
};

union u64 {
    int64_t     i;
    double      d;
};

int main() {
    union u32 a;
    union u64 b;

    a.i = 2;
    b.i = 2;

    printf("%g\n", a.f);
    printf("%g\n", b.d);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

结果输出:

2.8026e-45
9.88131e-324
Run Code Online (Sandbox Code Playgroud)

您的代码可能发生的情况是您使用的系统根据类型(int 值的整数寄存器和 fp 类型的浮点寄存器)在不同的寄存器中传递参数。所以调用将 2 放入一个整数寄存器中,但打印的值%f是用于参数的第一个浮点寄存器中的任何值——可能是 0,因为在调用之前没有运行 fp 代码。