小数

发布时间 2024-01-11 10:47:03作者: euv

float和double

float4 real 4bytes 精度 6个有效数字
float8 double precision 8bytes 精度 15个有效数字

如果输入数字的精度太高,那么可能发生四舍五入。 太接近零的数字,如果不能体现出与零的区别就会导致下溢错误。

精度损失。非常小的数会保存成0,无法准确存储0.1. 0.1 + 0.2 != 0.3

精度有损失。

任何十进制数字可以转换成3.1415... × 10n 的形式,同样的道理,任何十进制可以转换成二进制的形式,并表示成1.010101... × 2n的形式。所以计算机只要使用若干bit存储1.010101...(称为尾数),再用若干bit存储n(称为阶码)即可表示任何十进制小数。
精度损失发生的原因是十进制转换成二进制,M长度的0-9序列组成的十进制小数转换得到N长度的0和1序列组成的小数,其中N>M,甚至M有限长,但N会是无限长的情况。如果N大于计算机分配给存储尾数的bit数量,那么多出来的被截断,全部被解读成0,所以精度就发生了损失。
举例:
(0.1)10 = (0.000110011001100…)2
所以计算机无法精确的表示十进制的0.1。
注意事项:

  1. 两个浮点数做等值比较不能总是得到期望的结果。
    $2^{33}$
float double
alias float4
real
single
single precision
float8
double precision
storage size 4 bytes 8 bytes
significant digits 6 15

float和double支持正无穷大infinity、负无穷大negative infinity、非数字not-a-number。

3者的字面值需要用单引号包裹,依次是 'inf' '-inf' NaN

insert into "table" ("weight") values ('inf');
insert into "table" ("weight") values ('-inf');
insert into "table" ("weight") values ('NaN');

3者彼此之间以及与其他普通数字之间的关系如下:

NaN = NaN > inf = inf > 数字 > -inf = -inf

select 'NaN' = 'NaN'; -- true
select '-inf' = '-inf'; -- true
select 'inf' = 'inf'; -- true
select 'NaN' > 'inf'; -- true
select 'inf' > 0.0; -- true
select 0.0 > '-inf'; -- true

numeric

money decimal numeric