共计 1919 个字符,预计需要花费 5 分钟才能阅读完成。
这篇文章主要介绍“PostgreSQL 浮点数是怎么实现的”,在日常操作中,相信很多人在 PostgreSQL 浮点数是怎么实现的问题上存在疑惑,丸趣 TV 小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”PostgreSQL 浮点数是怎么实现的”的疑惑有所帮助!接下来,请跟着丸趣 TV 小编一起来学习吧!
众所周知, 计算机是以二进制方式存储数据, 而浮点数在序列化为二进制时可能会出现精度丢失 (IEEE 754 标准), 对于数据库实现来说, 会引入一个问题, 那就是那么两个浮点数之间在比较时在数据库是如何实现的?
下面是用于测试脚本:
testdb=# select 123.31::double precision 123.45::double precision;
;
一、数据结构
浮点数的编码可参考维基百科, 简单来说由三部分组成, 包括符号位, 有效数字和指数位. 其中, 在指数位全为 1(二进制的 1)时, 如果有效数字不全为 0, 那么这个数不是一个数(以 nan 表示).
二、源码解读
浮点数 (双精度) 的比较实现函数是 float8_cmp_internal, 逻辑比较简单.
其中 nan 亦即上面介绍的”不是一个数 nan”
/*
* float8{eq,ne,lt,le,gt,ge} - float8/float8 comparison operations
*/
float8_cmp_internal(float8 a, float8 b)
/*
* We consider all NANs to be equal and larger than any non-NAN. This is
* somewhat arbitrary; the important thing is to have a consistent sort
* order.
*/
if (isnan(a))
{ if (isnan(b))
return 0; /* NAN = NAN */
else
return 1; /* NAN non-NAN */
}
else if (isnan(b))
{
return -1; /* non-NAN NAN */
}
else
{ if (a b)//a b, 返回 1
return 1;
else if (a b)//a b, 返回 -1
return -1;
else
return 0;// 否则, 返回 0
}
}
在 C 语言中, 浮点数不要比较相等或不等, 但可以进行 , , =, = 运算.
但在 SQL 中, 可以进行相等或不等运算, 因为实质通过 ,
进行比较的实现而不是浮点数的直接等值比较实现.
三、跟踪分析
测试脚本
testdb=# select 123.31::double precision 123.45::double precision;
跟踪分析
(gdb) c
Continuing.
Breakpoint 1, float8_cmp_internal (a=123.31, b=123.45) at float.c:1056
1056 if (isnan(a))
查看内存中的数据(8 个字节, 以单字节 b 方式显示)
(gdb) x/8b a
0x7ffcd2cac728: 0xa4 0x70 0x3d 0x0a 0xd7 0xd3 0x5e 0x40
(gdb) x/8b b
0x7ffcd2cac720: 0xcd 0xcc 0xcc 0xcc 0xcc 0xdc 0x5e 0x40
(gdb)
同时, 我们用 c 语言来打印 123.31 和 123.45 的二进制编码作为对照
[xdb@localhost source]$ cat double_test.c
#include stdio.h
int main() {
double d1 = 123.31;
double d2 = 123.45;
printf(d1 : %llx \n , *((long *) d1));
printf(d2 : %llx \n , *((long *) d2));
[xdb@localhost source]$ gcc double_test.c -o dt
[xdb@localhost source]$ ./dt
d1 : 405ed3d70a3d70a4
d2 : 405edccccccccccd
输出的值与在跟踪分析中的内存值一致.
到此,关于“PostgreSQL 浮点数是怎么实现的”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注丸趣 TV 网站,丸趣 TV 小编会继续努力为大家带来更多实用的文章!