共計 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 小編會繼續努力為大家帶來更多實用的文章!