????????IEEE 全称为 Institute of Electrical and Electronics Engineers,即电气与电子工程师协会,是一个国际性的电子技术与信息科学工程师的协会,也是全球最大的非营利性专业技术学会。
????????IEEE 致力于电气、电子、计算机工程和与科学有关的领域的开发和研究,在太空、计算机、电信、生物医学、电力及消费性电子产品等领域已制定了 1300 多个行业标准,现已发展成为具有较大影响力的国际学术组织。
????????IEEE 出版有 70 多种期刊杂志,每年举办 300 多次专业会议,在电气及电子工程、计算机及控制技术领域中发表的文献占了全球将近 1/3。IEEE 定义的标准在工业界有极大的影响,其制定的标准也被国际社会广泛采用。
????????IEEE 754是国际电气和电子工程师协会(Institute of Electrical and Electronics Engineers,IEEE)制定的一种浮点数运算标准,全称为“IEEE Standard for Floating-Point Arithmetic”,首次发布于1985年,并在后续的1987、2008、2019年进行了修订。
????????IEEE 754标准定义了二进制浮点数的表示方法,包括正数、负数、零以及特殊值(如无穷大和NaN——Not a Number)。它主要规定了:
-->?1. 浮点数的格式:
包括单精度(32位)、双精度(64位)以及其他扩展精度格式。
每个浮点数由三部分组成:符号位(sign bit)、阶码(exponent field)和尾数(mantissa或fraction field)。
-->?2. 范围和精度:
根据不同的格式,浮点数可以表示非常大或非常小的数值,同时具有一定的有效数字精度。
-->?3. 特殊数值的表示:
例如,±0、±无穷大(infinity)以及非数字值(NaN)都有特定的编码方式。
-->?4. 运算规则:
包括加减乘除、舍入规则、比较大小等基本运算的行为规范。
????????由于其通用性和高效性,现今几乎所有的计算机系统和编程语言都采用或兼容IEEE 754标准来处理浮点数运算。
????????IEEE 754标准定义了浮点数在计算机中的表示和计算方式。下面以单精度(32位)浮点数为例,说明如何将一个十进制数转换成符合IEEE 754标准的二进制形式:
1、符号位(Sign bit)
最高位1位,0表示正数,1表示负数。
2、阶码(Exponent)
接下来8位,用于存储指数信息,通常采用偏移形式(即阶码减去某个固定的偏置值)来存储实际指数。
3、尾数(Mantissa或Fraction)
最后23位,存储小数部分,通常会省略第一位的隐藏位(该位始终为1),所以有效尾数是24位。
-->1. 处理符号位:
?? 如果原数为正,则符号位设为0;
?? 如果原数为负,则符号位设为1。
-->2. 转换为二进制并规范化:
?? 把十进制数转换为二进制科学计数法的形式,例如 (-1)^s * m * 2^e,其中s是符号,m是规格化的尾数(范围在1到2之间的小数),e是指数。
?? 规范化意味着确保尾数部分的第一位总是1(这个1在存储时会被隐含存储,不占用实际位数)。
-->3. 编码阶码:
?? 对于单精度浮点数,阶码的实际值等于原始指数加上一个偏置常数,通常是127(对于双精度则是1023)。
?? 计算 E = e + 127(对于单精度)并将结果以二进制补码形式存入8位阶码字段。
-->4. 编码尾数:
?? 将规格化后的尾数(去掉第一位的1后剩余的部分)转换为二进制,并填充到尾数字段。
-->5. 特殊情况处理:
?? 若数字为0,则尾数全为0,阶码根据实际情况决定是0还是最小负指数(表示±0)。
?? 若数字为无穷大或NaN,则阶码字段全为1,尾数全为0,通过符号位区分正负无穷大,而某些特定的尾数模式用于表示不同类型的NaN。
-->6. 组合所有部分:
?? 将符号位、阶码字段和尾数字段按照上述规则拼接起来形成32位的二进制数。
将十进制数33.758转换为IEEE 754单精度浮点数(32位)
-->1. 符号位(Sign):
? 因为33.758是正数,所以符号位S设为0。
-->2. 转换为二进制并规范化:
? 首先将整数部分33转换为二进制:33 = 100001
? 将小数部分0.758转换为二进制。这通常需要不断地乘以2并记录下整数部分直到达到足够的精度或者达到 尾数部分的最大位数。对于单精度浮点数,尾数有23位精度(不包括隐含的最高位1)。
计算得到近似的二进制小数表示:
0.758 ≈ 0.11000100110001...
注意这里为了简化说明,我们没有实际展示完整精确的转换过程,但理论上要确保尾数部分在截断到23位后尽可能接近原始值。
-->3. 规格化:
移动小数点使第一位数字成为1(隐含),并相应地调整指数。由于原数大于1,我们需要向左移动两位得到规范化的结果:
1.1000100110001... * 2^2
-->4. 编码指数(E):
规范化后的指数是2,加上偏置常数127得到实际存储的指数E:
E = 2 + 127 = 129
将129转换为8位无符号偏移指数的二进制形式(即二进制补码形式,但因为这里是正数所以与无符号等价):
129 = 10000001 (二进制)
-->5. 编码尾数(M):
将规范化后的尾数去掉第一位的1,剩余部分填充到23位尾数字段:
Mantissa = 1.000100110001... -> 000100110001... (忽略首位的1,保留23位)
-->6. 组合成最终的单精度浮点数:
将符号位、指数和尾数组合起来:
单精度浮点数: S Exponent Mantissa
0 10000001 000100110001...
最后,将它们拼接起来形成32位的单精度浮点数。
注意:以上步骤中的尾数部分可能因为手头条件限制而进行了近似处理,在实际操作中,尾数应准确转换至23位,并且有可能需要四舍五入或舍去最低有效位以适应标准格式要求。同时,指数也需要正确按照IEEE 754单精度浮点数格式进行编码。
?
????????在IEEE 754标准出现之前,业界没有一个统一的浮点数标准,许多计算机制造商都设计了自己的浮点数规则和运算细节。当时,人们更加注重实现速度和简易性,而非数字的精确性。
?????????直到1985年,Intel公司打算为其8086微处理器引入一种浮点数协处理器,聪明地意识到,作为设计芯片者的电子工程师和固体物理学家们,也许并不能通过数值分析来选择最合理的浮点数二进制格式。
????????于是Intel公司邀请加州大学伯克利分校的William Kahan教授——最优秀的数值分析家之一来为8087 FPU设计浮点数格式;而这个家伙又找来两个专家来协助他,于是就有了KCS组合(Kahn, Coonan, and Stone)。
????????他们共同完成了Intel的浮点数格式设计,而且完成得如此出色,以致于IEEE组织决定采用一个非常接近KCS的方案作为IEEE的标准浮点格式。? ? ? ??
????????目前,几乎所有计算机都支持该标准,它大大改善了科学应用程序的可移植性。