c - C 不能打印/表示非规范化浮点数吗?
问题描述
$ 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
代码:
#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;
}
编译:
$ gcc floatingpointtypes.c
执行:
$ ./a.out
int "2" as %.128f: 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
int "2" as %.128lf: 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
int "2" as %.128LF: 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
当整数 2 的二进制被解释为 IEEE-754 单精度(32 位)或双精度(64 位)浮点数格式时,它是非规格化浮点数(指数位全为 0),十进制的结果值为 2e- 148.
问题:
为什么我的代码打印 0?是因为 C 无法将非规范化浮点数解释为正确的值吗?
解决方案
如果要将 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;
}
结果输出:
2.8026e-45
9.88131e-324
您的代码可能发生的情况是,您使用的系统根据类型在不同的寄存器中传递参数(整数寄存器用于 int 值,浮点寄存器用于 fp 类型)。所以调用将 2 放入一个整数寄存器,但打印的%f
值是用于参数的第一个浮点寄存器中的任何值——可能是 0,因为在调用之前没有运行任何 fp 代码。
推荐阅读
- performance - 查询计划中的成本百分比 - 似乎不准确,我错过了什么吗?
- authorization - Argo events 对 eventbus 内部 NATS 的授权
- html - Genie.jl 是否有完整的现代网站启动文档?
- firebase - 无法在颤振中构建自定义小部件
- mysql - 计算一个 id 出现在多少个不同表中的最佳方法?我有大约 25 张桌子
- javascript - 第二个异步未运行
- javascript - 在 Web 浏览器控制台中动态检查 JavaScript 模块导出
- notepad++ - 在记事本++中调用函数时如何显示python3函数文档字符串
- java - 使用 Amazon S3 Java Api,您可以在 ListObject 中使用 --query 吗?
- jpa - 如何使用 JPA 本机查询获取映射对象(外键)?