PostgreSQL浮点数是怎么实现的
这篇文章主要介绍“PostgreSQL浮点数是怎么实现的”,在日常操作中,相信很多人在PostgreSQL浮点数是怎么实现的问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”PostgreSQL浮点数是怎么实现的”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
众所周知,计算机是以二进制方式存储数据,而浮点数在序列化为二进制时可能会出现精度丢失(IEEE 754标准),对于数据库实现来说,会引入一个问题,那就是那么两个浮点数之间在比较时在数据库是如何实现的?
下面是用于测试脚本:
testdb=#select123.31::doubleprecision>123.45::doubleprecision;;一、数据结构
浮点数的编码可参考维基百科,简单来说由三部分组成,包括符号位,有效数字和指数位.其中,在指数位全为1(二进制的1)时,如果有效数字不全为0,那么这个数不是一个数(以nan表示).
二、源码解读浮点数(双精度)的比较实现函数是float8_cmp_internal,逻辑比较简单.
其中nan亦即上面介绍的”不是一个数nan”
/**float8{eq,ne,lt,le,gt,ge}-float8/float8comparisonoperations*/intfloat8_cmp_internal(float8a,float8b){/**WeconsiderallNANstobeequalandlargerthananynon-NAN.Thisis*somewhatarbitrary;theimportantthingistohaveaconsistentsort*order.*/if(isnan(a)){if(isnan(b))return0;/*NAN=NAN*/elsereturn1;/*NAN>non-NAN*/}elseif(isnan(b)){return-1;/*non-NAN<NAN*/}else{if(a>b)//a>b,返回1return1;elseif(a<b)//a<b,返回-1return-1;elsereturn0;//否则,返回0}}
在C语言中,浮点数不要比较相等或不等,但可以进行<,>,>=,<=运算.
但在SQL中,可以进行相等或不等运算,因为实质通过>,<进行比较的实现而不是浮点数的直接等值比较实现.
测试脚本
testdb=#select123.31::doubleprecision>123.45::doubleprecision;
跟踪分析
(gdb)cContinuing.Breakpoint1,float8_cmp_internal(a=123.31,b=123.45)atfloat.c:10561056if(isnan(a))
查看内存中的数据(8个字节,以单字节b方式显示)
(gdb)x/8b&a0x7ffcd2cac728:0xa40x700x3d0x0a0xd70xd30x5e0x40(gdb)x/8b&b0x7ffcd2cac720:0xcd0xcc0xcc0xcc0xcc0xdc0x5e0x40(gdb)
同时,我们用c语言来打印123.31和123.45的二进制编码作为对照
[xdb@localhostsource]$catdouble_test.c#include<stdio.h>intmain(){doubled1=123.31;doubled2=123.45;printf("d1:%llx\n",*((long*)&d1));printf("d2:%llx\n",*((long*)&d2));}[xdb@localhostsource]$gccdouble_test.c-odt[xdb@localhostsource]$./dtd1:405ed3d70a3d70a4d2:405edccccccccccd
输出的值与在跟踪分析中的内存值一致.
到此,关于“PostgreSQL浮点数是怎么实现的”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。