IEEE浮点数表示--规格化/非规格化/无穷大/NaN


1.规格化的值

以sizeof(float)=4为例:


1.5的浮点数表示:

1)1.5转换为2进制:1.1

2)转换:0.1*2^0 (整数部分的1省略)

3)得到阶码:127+0=127,即0111 1111 (指数部分可能是负数,为了兼容负数,需要+127)

4)得到尾数:1,后面补齐0

5)确定符号位:0

所以,1.5的浮点数表示如下:

符号位:1bit阶码:8bits尾数:23bits
00111 11111000 0000 0000 0000 0000 000


程序验证如下:

#include <stdio.h>
#include <stdlib.h>

int main()
{
	float f = 1.5;
	printf("%x", *(int*)&f);//打印3fc00000
	return 0;
}
3fc00000即:

0  01111111  1000  0000 0000 0000 0000 000

一致!

2.非规格化的值

即,所有的阶码都是0
符号位:1bits阶码:8bits尾数:23bits
x0000 0000xxxx xxxx xxxx xxxx xxxx xxx
用途有2:
1)提供了一种表示值0的方法
2)表示那些非常接近于0.0的数,对“逐渐溢出”属性的支持

代码示例:
////小端模式机器实验
#include <stdio.h>
#include <stdlib.h>
typedef struct _float
{
	int w:23;
	int j:8;
	int s:1;
}Float;
int main()
{
	float f = 0;
	Float obj;
	obj.s = 0;
	obj.j = 0;
	obj.w = 0x400000;
	f = *(float*)(&obj);
	printf("%f", f);//输出0.000000
	return 0;
}


3.无穷大

符号位:1bits阶码:8bits尾数:23bits
x1111 11110000 0000 0000 0000 0000 000
代码示例:
#include <stdio.h>
#include <stdlib.h>
typedef struct _float
{
	int w:23;
	int j:8;
	int s:1;
}Float;
int main()
{
	float f = 0;
	Float obj;
	obj.s = 0;
	obj.j = 0xff;
	obj.w = 0x0;
	f = *(float*)(&obj);
	printf("%f", f);//输出inf
	return 0;
}


4.NaN

符号位:1bit阶码:8bits尾数:23bits
x1111 1111非全0
代码示例:
#include <stdio.h>
#include <stdlib.h>
typedef struct _float
{
	int w:23;
	int j:8;
	int s:1;
}Float;
int main()
{
	float f = 0;
	Float obj;
	obj.s = 0;
	obj.j = 0xff;
	obj.w = 0x1;
	f = *(float*)(&obj);
	printf("%f", f);//输出nan
	return 0;
}




### 浮点数规格化的概念 浮点数规格化是指将浮点数调整到一种标准化形式,使得其表示更加统一和高效。具体来说,在二进制浮点数中,规格化意味着使尾数(mantissa)的第一个有效位总是1,并将其隐含起来不存储,从而节省空间并提高精度[^1]。 对于零的二进制浮点数而言,规格化后的形式可以写成 \( (-1)^s \times 1.f \times 2^{e-bias} \),其中\( s \)代表符号位,\( f \)是小数部分组成的分数,而\( e \)则是指数字段的实际值减去偏置量(bias)[^4]。 当处理常接近于零的小数值时,可能会采用规格化形式来增加可表达范围内的最小正数大小;而对于其他情况,则通常都使用规格化形式以获得更高的相对精度[^3]。 ### 规格化的方法 为了实现浮点数规格化,需要遵循一定的步骤: - **确定符号位**:根据原始数据判断该数为正值还是负值; - **提取整数与小数部分**:分离出待转换十进制实数中的整数部分和纯小数部分; - **计算二进制下的科学记数法**:找到能够移除前导零的最大幂次k,使得原数等于某个介于\[1,2)\区间内乘上\(2^k\)的结果; - **设置指数域**:按照所选编方式设定合适的指数偏差bias并将实际使用的指数设为\( k+bias \); - **构建尾数域**:去掉最左边那个必然存在的'1.'之后剩下的二进制串即构成最终要存入机器里的尾数部分[^2]。 ```python def normalize_float(sign_bit, exponent_bits, fraction_bits): """ A simplified function to demonstrate the normalization process of a floating-point number. Args: sign_bit (int): The sign bit indicating positive or negative. exponent_bits (list[int]): List representing binary digits for the exponent part. fraction_bits (list[int]): List representing binary digits after decimal point. Returns: tuple: Normalized components including new_exponent and normalized_fraction as lists. """ # Assume initial unnormalized form is given by these parameters # Find position where first '1' appears in fractional bits shift_count = next((i for i, bit in enumerate(fraction_bits) if bit), None) # Adjust exponent accordingly based on shifting required to make leading digit be '1' adjusted_exponent = sum([bit * pow(2, idx) for idx, bit in enumerate(reversed(exponent_bits))]) - shift_count # Remove leading zeros from fraction bits until reaching first one trimmed_fraction = fraction_bits[shift_count:] return ([sign_bit], [adjusted_exponent], trimmed_fraction) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值