IEEE754 浮点数表示

 

IEEE754 浮点数表示

IEEE754 浮点数标准是当今在计算机中使用最为普遍的浮点数表示方法。这篇文章将对IEEE浮点数表示方法给出一个简短的介绍。

1.       什么是浮点数

计算机中小数的小数点并不是用某个数字表示的,而是用隐含的小数点的位置来表示的。根据小数点的位置是否固定,又可以分为定点表示和浮点表示。浮点数顾名思义就是小数点不固定,是浮动的,要处理的数既有整数部分又有小数部分。在计算机中一般采用浮点表示方法。

2.       存储结构

IEEE浮点数由三个基本的部分组成:符号(Sign)、指数(Exponent)和尾数(mantissa)。其中尾数由分数(fraction)和隐含的前导数字(leading digit)组成。指数的基数为2。下面给出单精度和双精度浮点数的存储结构。

 

Sign

Exponent

Fraction

Bias

Single Precision

1[31]

8[30-23]

23[22-0]

127

Double Precision

1[63]

11[62-52]

52[52-0]

1023

2.1. 符号位

       0: 正数   1: 负数

2.2. 指数

指数应该既能表示正数也能表示负数。为了实现找个目的,存储的指数在实际的指数上被加上一个偏差。对于IEEE单精度数而言,这个偏差是127(双精度为1023)。

2.3. 尾数

       尾数位的多少反映了数的精确程度。它由一位隐含的前导位和分数位组成。前导位为1,不需要显示表示出来。这样,尾数实际上由24位组成。

3.       浮点数表示范围

正浮点数的表示范围可以被分成规范化的数和非规范化的数(只用了一部分分数的精度)

 

Denormalized

Normalized

Approximate Decimal

Single Precision

± 2-149 to ( 1-2 -23 )×2-126

± 2-126 to ( 2-2 -23 )×2127

± ~10-44.85 to ~1038.53

Double Precision

±2-1074 to ( 1-2 -52 )×2-1022

± 2-1022 to ( 2-2 -52 )×21023

± ~10-323.3 to ~10308.3

有五个不同的数值范围单精度数不能表示。

¨         小于-( 2-2 -23 ) × 2127的负数:(negative overflow)

用规范化形式表示的浮点数最小负数为:-( 2-2 -23 ) × 2127,其内存表示为:

1 11111110 11111111111111111111111

¨         大于-2-149的负数:(negative underflow

用非规范化形式表示的浮点数最大负数为:-2-149,其内存表示为:

1 00000000 00000000000000000000001

¨         零:0最为一种特殊值进行处理

¨         小于2-149的负数:(positive underflow

用非规范化形式表示的浮点数的最小正数为:2-149 ,其内存表示为:

0 00000000 00000000000000000000001

¨         大于( 2-2 -23 ) × 2127的正数:(positive overflow

用规范化的形式表示的浮点数的最大正数为:-( 2-2 -23 ) × 2127,其内存表示为:

1 11111101 11111111111111111111111

上溢指的是所要表示的数值太大以至于不能被表示,下溢不太严重,因为它只表示精度的损失。可以通过接近零得到保证。

这样IEEE浮点数所能表示的有效范围如下表:

 

Binary

Decimal

Single

± ( 2-2 -23 ) × 2127

~ ± 1038.53

Double

± ( 2-2 -52 ) × 21023

~ ± 10308.25

4.       特殊值

IEEE保留了指数域全零和全1表示不同的特殊值。

¨         零(Zero

由于前导1的原因,0不能以正常的形式在浮点数中表示出来,必须以特殊值的形式对待。零是一个指数域和尾数域全零的特殊值,有+0和-0之分,但他们相比较是相等的。

¨         非规范化

如果指数全零,而尾数不为零,那么这就是一个非规范化的数,它并不假定前导1的存在。

¨         无穷

无穷是通过指数域全1,尾数域全0表示的。符号位区分正无穷和负无穷。

¨         不是一个数(Not A Number

NaN用于表示一个并不是真实数字的值。NaN是通过指数域全1,尾数域不为零表示的。由两种NaNQNaNQuiet NaN)和SNaNSignalling NaN)。

关于这两种NaN的区别,可以参考下面的英文解释:

A QNaN is a NaN with the most significant fraction bit set. QNaN's propagate freely through most arithmetic operations. These values pop out of an operation when the result is not mathematically defined.

An SNaN is a NaN with the most significant fraction bit clear. It is used to signal an exception when used in operations. SNaN's can be handy to assign to uninitialized variables to trap premature usage.

Semantically, QNaN's denote indeterminate operations, while SNaN's denote invalid operations.

5.       特殊操作

特殊值上的操作在IEEE中被良好的定义。简单的情况是任意的包含NaN的操作都产生NaN。其他操作如下:

Operation

Result

n ÷ ±Infinity

0

±Infinity × ±Infinity

±Infinity

±nonzero ÷ 0

±Infinity

Infinity + Infinity

Infinity

±0 ÷ ±0

NaN

Infinity – Infinity

NaN

±Infinity ÷ ±Infinity

NaN

±Infinity × 0

NaN

 

6.       总结

下面给出了表示一种表示方法对应的值:(b bias         

Sign

Exponent(e)

Fraction(f)

Value

0

00..00

00..00

+0

0

00..00

00..01

11..11

正非规范化数:

0.f × 2(-b+1)

0

00..01

11..11

00..00

11..11

正规范化数:

1.f × 2(e-b)

0

11..11

00..00

Infinity

0/1

11..11

00..01

01..11

SNaN

0/1

11..11

10..00

11..11

QNaN

1

00..00

00..00

-0

1

00..00

00..01

11..11

负非规范化数:

-0.f × 2(-b+1)

1

00..01

11..10

00..00

11..11

负非规范化数:

1.f × 2(e-b)

1

11..11

00..00

-Infinity

 

在C语言中,将十进制转换为IEEE 754浮点数(也称为单精度或双精度浮点数,取决于`float`或`double`类型)通常需要两个步骤:首先将十进制数转换为二进制小数,然后根据IEEE 754标准进行编码。 **步骤1:十进制到二进制小数** 1. 首先,你需要了解十进制整数和小数如何在二进制中表示。对于整数部分,可以逐位除以2并记录余数,直到商为0;对于小数部分,直接保留或按照所需精度转换。 2. 对于小数部分,你需要找到足够多的小数位数以精确表示原始十进制值。这可能会涉及无限循环,但实际上由于IEEE 754的特殊存储方式,只需要有限位数。 **步骤2: IEEE 754编码** - **阶码(Exponent)**: 十进制小数值通过移位和偏移得到其对应的指数,区分正负和正常数、零和无穷大、非正常数等状态。 - **尾数(Mantissa)**: 小数部分经过偏置后作为尾数( significand),通常会去掉前导零,并用1补足至特定长度(如`float`是23位,`double`是52位)。 - **符号位(Sign bit)**: 根据数值的正负来设置符号位,通常是最高位。 下面是一个简单的伪代码示例: ```c // 假设输入是 decimal_num 和 float_type 类型 int* int_part = &decimal_num; // 整数部分指针 float_type* fraction_part = (float_type*)&decimal_num + sizeof(int); // 尾数部分指针 // 获取二进制小数部分并将其转换为IEEE 754格式 // ... 这里省略了具体的转换算法 ... // 现在 *fraction_part 是IEEE 754格式的尾数 // *int_part 是阶码偏置后的形式 ``` 注意,实际操作时可能需要使用库函数(如`memcpy`)来处理数据转换,并确保内存对齐。此外,计算阶码和尾数可能涉及到复杂的数学运算,例如查表法或位移操作。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值