目录

  • 一、实数表示的发展历程
  • 定点数
  • 浮点数
  • 二、浮点数的表示方法
  • 规格化数
  • 特殊值
  • 非规格化数
  • 三、 浮点数的运算
  • 加减运算
  • 运算步骤
  • 异常处理
  • 乘除运算
  • 浮点数运算常见问题


一、实数表示的发展历程

实数的表示需要解决小数点的位置表示问题,小数点约定在固定位置的称为定点数,小数点约定为可以浮动的称为浮点数。
(实数包括整数,只是小数问题更难解决)

定点数

定点数(Fixed Point Number)(与浮点数相对应)
在这种表达方式中,小数点固定的位于实数所有数字中间的某个位置。

定点小数:小数点固定在数最左边
定点整数:小数点固定在数点最右边

例子:
货币的表达;比如 99.00 或者 00.99 可以用于表达具有四位精度(Precision),小数点后有两位的货币值。
SQL 中的 NUMBER 数据类型;

定点数的表示参见另一篇文章(待完成)

浮点数

采用科学计数法来表示实数。
用一个尾数(Mantissa )(更准确的说法是Significand 有效数字),一个基数(Base),一个指数(Exponent)以及一个表示正负的符号来表达实数。
利用指数达到了浮动小数点的效果,从而可以灵活地表达更大范围的实数(扩大了整数表示范围,可以表示小数点位置不同的小数)

二、浮点数的表示方法

对任意实数X可以表示成如下形式:
SQL SERVER 怎么讲带小数点的数字转为字符串 sql将数字转化为定点小数_浮点数

各项含义:
S为0/1,用于表示符号,0正1负;
M用二进制定点小数表示,称为X的尾数(mantissa)
E用二进制定点整数表示,称为X的阶/指数(exponent);阶的编码称为阶码,采用移码形式。
R是基数(radix,base),可以在机器中取2,4,16等(一般为2)

在基数R一定时,尾数M的尾数即X的有效位数,有效位数越多,精度越高。
采用IEEE 754标准float 和double 分别可以精确表示7和17个精确有效数字的十进制数。

阶的值决定了小数点的位置。
阶的范围决定了数X的表示范围(在运算的溢出判断中可以深刻理解这一点)

规格化数

特殊值

非规格化数

三、 浮点数的运算

加减运算

运算步骤

具体分为四个步骤:

(1)对阶
目的:使两个数的阶相等,便于尾数直接进行加减运算
原则:小阶向大阶看齐,阶小的尾数右移,右移的位数等于两个阶的差的绝对值
具体操作:

  1. 计算:计算两个阶的差的绝对值
  2. 移动:阶小的尾数按照原码小数方式右移,符号位不参与移动,数值位要将隐含的1右移到小数部分,前面空出的位补0;低位移出的位不丢弃,而是存储下来参与计算。

例子:float x = 1.5 , float y = -125.25,计算x+y。
x 机器数为 0 0111 1111 100 0000 0000 0000 0000 0000
y 机器数为 1 1000 0101 111 1010 1000 0000 0000 0000

对阶操作如下:
1.计算两个阶的差的绝对值:

SQL SERVER 怎么讲带小数点的数字转为字符串 sql将数字转化为定点小数_移出_02

这里用到的知识点有补码公式和移码公式

2.移动:计算得到y的阶比x的阶大6,所以x向y看齐,尾数向右移6位。
所以x阶码变为与y相同,尾数为 0.000001 100 000…000 (后面多出的6位也保留)

(2)尾数加减
对阶后两个浮点数可以直接尾数相加减。即定点原码小数的加减运算。
注意:1.隐藏的1也要参与运算;2.保留的附加位也要参与运算。

(3)尾数规格化
尾数加减后可能会出现不满足规格化形式的数,如1b.bbbb 或者0.001bbbbb,这两种形式分别需要进行右规和左规处理。
1.右规 1b.bbbb
尾数右移一位,阶码加1。
最后一位移出时要考虑舍入???

2.左规 0.00001bbb
阶码逐次减1,尾数逐次左移。
有两种情况结束上述操作:
·直到第一位1移动到小数点左边:也就是第一位1作为默认隐藏位
·阶码全为0:也就是非规格化浮点数

(4)尾数的舍入
因为在(1)对阶 或者 (3)中右规时 需要将移出的位保留下来保证运算精度,所以对这部分数作舍入处理,还原结果为标准的IEEE 754格式

1.附加位个数:
IEEE 754 规定所有运算的中间结果都必须至少保留两位附加位,两位附加位在尾数后面:
尾数【保护位guard】【舍入位round】

IEEE 754 为了进一步提高精度还规定可以再加上一位:粘位sticky
只要舍入位右边存在非零数则粘位置1,否则置0;

2.舍入方法:
·就近舍入:一般采用这种方法,精确度最高(默认)
非中间值:0舍1入
中间值:强迫结果为偶数(若舍入前尾数最后一位为0,则不变,否则加1)
舍入结果可能变大也可能变小。

关于舍入误差和可表示数的间隔区间:

SQL SERVER 怎么讲带小数点的数字转为字符串 sql将数字转化为定点小数_浮点数_03


·朝正无穷方向舍入:取数轴上右边最近可表示数

·朝负无穷方向舍入:取数轴上右边最近可表示数

·朝0舍入:直接截取

异常处理

主要的异常时指阶码的溢出,产生溢出的原因:
尾数右规或舍入时可能需要阶码加1或者减1,而阶码存在范围(单精度:0000 0001- 1111 1110)。
阶码上溢:如果阶码加1后为全1即为阶码上溢,一般机器通过将结果置为正无穷或者负无穷来处理这种异常;
阶码上溢:如果阶码减1后为全0即为阶码下溢,按照非规格化数处理(尾数不变,阶码全0)

乘除运算

先确定参与运算的操作数是否为规格化浮点数,然后进行乘除运算,规格化,舍入和异常处理。
与加法相比省去了对阶的步骤。

浮点数运算常见问题

  1. 大数吃小数——不满足结合律
    具体解释:指在一个较大的数和一个较小的数进行加减运算时,由于需要进行小阶向大阶对阶的操作,阶小的数右规导致有效位数右移后被舍去,结果为大的数本身。
    例子:
  2. SQL SERVER 怎么讲带小数点的数字转为字符串 sql将数字转化为定点小数_定点数_04

  3. 不满足交换律
    主要是乘法运算中,大数相乘出现溢出的情况,导致乘法结果为无穷。
    例子:
  4. SQL SERVER 怎么讲带小数点的数字转为字符串 sql将数字转化为定点小数_移出_05