浮点数规格化

浮点数的几种特殊情况

当阶码是0的时候
(1)0的表示
对于阶码为0或255的情况,IEEE754标准有特别的规定:
如果 阶码E 是0 并且尾数M 是0,则这个数的真值为±0(正负号和数符位有关)。

因此+0的机器码为:0 00000000 000 0000 0000 0000 0000 0000。
     -0的机器码为  0 0000000 000 0000 0000 0000 0000 0000。
当阶码是255的时候
(2)+∞和−∞的表示
如果 阶码E = 255 并且尾数M全是0,则这个数的真值为±∞(同样和符号位有关)。
因此+∞的机器码为0 11111111 000 0000 0000 0000 0000 0000。
    -∞的机器码为 1 11111111 000 0000 0000 0000 0000 0000。
NaN(Not a Number)
如果 E = 255 并且 M 不是0,则这不是一个数(NaN)。

浮点数的精度和数值范围

根据上面的探讨,浮点数可以表示-∞到+∞,这只是一种特殊情况,显然不是我们想要的数值范围。

以32位单精度浮点数为例,阶码E由8位表示,取值范围为0-255,去除0和255这两种特殊情况,那么指数e的取值范围就是 E范围(1,254) e=E-127
1-127=-126
254-127=127。 e范围(-126,127)
解释一下:阶码E由8位表示,取值范围为0-255。去除了0和255 就只剩1~254
(1)最大正数
因此单精度浮点数最大正数值的符号位S=0,阶码E=254,指数e=254-127=127,尾数M=111 1111 1111 1111 1111 1111,其机器码为:
0 11111110 111 1111 1111 1111 1111 1111。

(−1)S×1.M×2^e (此时e等于127)
=[1+(1-2^-23)]* 2^127

(2)最小正数
最小正数符号位S=0,阶码E=1,指数e=1-127=-126,尾数M=0,其机器码为
0 00000001 000 0000 0000 0000 0000 0000。
那么最小正数为:
(−1)S×1.M×2^e (此时e等于-126)
=+(1.0)×2^−126

(3)最大负数
最大负数符号位S=1,阶码E=1,指数e=1-127==-126,尾数M=0,机器码与最小正数的符号位相反,其他均相同,
1 00000001 000 0000 0000 0000 0000 0000。

那么最大负数 为:
(−1)S×1.M×2^e (此时e等于-126)
=−(1.0)×2^−126

(4)最小负数
符号位S=0,阶码E=254,指数e=254-127=127
尾数M=111 1111 1111 1111 1111 1111,
其机器码为:1 11111110 111 1111 1111 1111 1111 1111。

那么最小负数 为:
(−1)S×1.M×2^e (此时e等于127)
=−[1+(1-2^-23)] ×2^127

  • 3
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C#中,浮点数(如`double`或`float`)有时需要规范化,这是为了提高它们的表示效率和精度。浮点数通常用阶码(exponent)和尾数(mantissa)来存储,其中尾数可能包含前导零。规范化过程涉及以下步骤: 1. **舍入到最近的规格化形式**: - 如果尾数(小数部分加上1)的第一个非零数字在小数点之前,那么将尾数向左移动一位,增加阶码。 - 如果尾数的第一个非零数字在小数点之后,那么不需要移动,因为这已经是规格化形式。 - 如果移动后尾数变为0(即变成了纯小数0.0),那么这表明原数太小,可能会丢失精度,所以通常会设置为最小规格化值(例如`double.MinValue`或`float.Epsilon`)。 2. **处理溢出和下溢**: - 如果移动后阶码超过最大值,表示结果溢出,可能会导致精度丢失或异常。 - 如果阶码减到最小值且尾数为0,表示结果小于最小可表示值,这可能导致下溢。 3. **保留精度**: - 根据浮点数类型,规范化后的结果可能丢失一些小数位,但这通常不会影响数学运算的正确性,因为大部分操作是基于近似值进行的。 以下是一个简单的C#代码片段来演示如何规范化一个double类型的浮点数: ```csharp public static double NormalizeDouble(double value) { // 将尾数乘以10以避免精度损失 double adjustedValue = value * 10.0; int exponent = BitConverter.DoubleToInt32LittleEndian(BitConverter.GetBytes(adjustedValue)); // 规范化尾数 while ((exponent & 0x7ff) == 0x7ff && adjustedValue != 0) // 阶码全为1, 并且不为0 { adjustedValue /= 10.0; // 移动小数点 exponent -= 128; // 减少阶码 } // 把结果放回正确的格式 byte[] bytes = BitConverter.GetBytes(BitConverter.ToInt64LittleEndian(BitConverter.GetBytes(exponent << 52 | BitConverter.IntToUInt32LittleEndian(BitConverter.GetBytes(adjustedValue))))); return BitConverter.ToDouble(bytes, 0); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值