C语言中32位浮点数的格式

以 GNU C为例,它遵循 IEEE 754-2008标准中制定的浮点表示规范。在该规范中定义了 5种不同大小的基础二进制浮点格式,包括:16位,32位,64位,128位,256位。其中,32位的格式被用作标准 C类型的 float,64位的格式被用作标准 C类型的 double,128位的格式被用作标准 C类型的 long double。

每种浮点格式都由三部分组成,包括:1个比特的符号位、若干比特的指数位、若干比特的小数位,如下图所示:

以 C语言中 float类型(32位浮点)为例,它的符号位占 1位,指数位占 8位,小数位占 23位,如下图所示:

值得注意的是,

1)指数位编码的指数以 2为底数,若要表示很小的数,例如 1/(2^n) == 2^(-n),则指数位会出现负数 (-n),那么还需要专门的符号位来表示,因此指数位是以 127为偏移的,也就是说,一个数在用浮点数来表示时,其指数位的值是实际指数值加上 127。对于 64位浮点数,它的指数位是 11个比特,以 1023为偏移。

2)浮点数的小数部分是将该浮点数表示为 2^n * 1.m后,0.m那部分的数值,也就是说,整数部分始终是 1,且被忽略了(不用保存),这样就能省出一位来表示更高的精度。

举例来说,

1)0.5 = 2^(-1) * 1.0,其指数位为 (-1 + 127),小数位为 0.0,其二进制是:0 01111110 00000000000000000000000,也就是 0x3F000000。

2)5 = 2^(2) * 1.25,其指数位为 (2 + 127),小数位为 0.25,其二进制是:0 10000001 01000000000000000000000, 也就是 0x40A00000。

测试代码如下:

c 复制代码
#include <stdio.h>

int main(void)
{
	float a = 0.5;
	unsigned int *b = (unsigned int*)&a;

	printf("b = 0x%X\n", *b);

	a = 5;
	printf("b = 0x%X\n", *b);
}

程序运行结果如下:

bash 复制代码
$ gcc -o main main.c 
$ ./main 
b = 0x3F000000
b = 0x40A00000

从 32位浮点的指数宽度来看,理论上,它可以表示很大的数,比如:2^(128) * 1.9999999,这比我们 32位整型能表示的范围(2^(32) - 1)大的多,但受限于浮点小数位的宽度,有些 32位整型数是无法用浮点数来表示的,也就是会出现空洞,原因是浮点数的小数部分精度有限,当小数部分比 1/(2^23)还小时,就无法准确表示该整型数,例如:2^(24) + 1这个数用 32位整型来表示是没有问题的,但用 32位浮点来表示,则会被舍入为:2^24。

测试代码如下:

c 复制代码
#include <stdio.h>

int main(void)
{
	float a = 1 << 24;
	unsigned b = 1 << 24;
	printf("a = %f, b = %u\n", a, b);

	a += 1;
	b += 1;
	printf("a = %f, b = %u\n", a, b);

	return 0;
}

程序运行结果如下:

bash 复制代码
$ gcc -o main main.c
$ ./main 
a = 16777216.000000, b = 16777216
a = 16777216.000000, b = 16777217

参考资料:

  1. https://www.gnu.org/software/c-intro-and-ref/manual/html_node/Floating-Representations.html
  2. https://docs.nvidia.com/cuda/floating-point/index.html
相关推荐
奋斗的阿狸_198620 分钟前
ESP32-S3 + ES7210 四通道麦克风录音上传方案
c语言·开发语言·fpga开发
2401_8628808236 分钟前
iMX6ULL 驱动工程搭建 + LED 灯驱动
c语言·驱动开发·嵌入式硬件
ACP广源盛139246256731 小时前
Type‑C 扩展坞方案选型笔记|国产 DP1.4 转 HDMI2.0 桥接芯片 GSV2201S @ACP评估
c语言·开发语言·笔记·硬件架构·硬件工程·国产芯片
沐欣工作室_lvyiyi1 小时前
超市智能货架系统设计与实现(论文+源码)
c语言·单片机·课程设计·电子信息工程毕业设计·黑龙江工商学院·广州工商学院·成都工业学院
C++ 老炮儿的技术栈1 小时前
static的作用
c语言·c++·人工智能·单片机·c
小小龙学IT3 小时前
Go 语言 cgo 与 C/C++ 互操作深度解析:从 fwlib 直连到工业数采网关实战系列
c语言·c++·golang
老王爱玩车4 小时前
动态内存管理
c语言·开发语言·学习·面试
Logic1015 小时前
C语言/数据结构数位DP题解:平滑排列数字统计——区间内相邻位差不超过K的数字个数
c语言·数据结构·动态规划·时间复杂度·数位dp·算法题·前导零处理
Zwawa5 小时前
把 AO 接回来:黑线和白底之间到底差了多少
c语言·单片机·嵌入式
C++ 老炮儿的技术栈6 小时前
char (*csConnectName)[256]; 和 char csConnectName [256] 有什么区别
java·c语言·开发语言·c++·人工智能·算法·c