Ngemva kokushicilelwa
Imibhalo ye-PostgreSQL isho ngamafuphi: "Ukuphathwa kwalawo maphutha kanye nokusatshalaliswa kwawo ngesikhathi sokubala kuyisihloko salo lonke igatsha lezibalo nesayensi yekhompyutha, futhi akumbozwanga lapha" (ngenkathi kubhekiselwa kumfundi ngezinga le-IEEE 754 ngobuhlakani). Hlobo luni lwamaphutha okushiwo lapha? Ake sixoxe ngazo ngokulandelana kwazo, futhi kuzosheshe kucace ukuthi kungani ngiphinde ngathatha ipeni.
Ake sithathe isibonelo isicelo esilula:
********* ЗАПРОС *********
SELECT 0.1::REAL;
**************************
float4
--------
0.1
(1 строка)
Ngenxa yalokho, ngeke sibone lutho olukhethekile - sizothola okulindelekile okungu-0.1. Kodwa manje ake siyiqhathanise no-0.1:
********* ЗАПРОС *********
SELECT 0.1::REAL = 0.1;
**************************
?column?
----------
f
(1 строка)
Ayilingani! Yeka izimangaliso! Kodwa ngokuqhubekayo, ngaphezulu. Omunye uzothi, ngiyazi ukuthi i-REAL iziphatha kabi ngezingxenye, ngakho-ke ngizofaka izinombolo eziphelele lapho, futhi yonke into izohamba kahle ngabo. Kulungile, masiphonsa inombolo 123 ku-REAL:
********* ЗАПРОС *********
SELECT 123456789::REAL::INT;
**************************
int4
-----------
123456792
(1 строка)
Futhi kwaba ngu-3 ngaphezulu! Yilokho, i-database ekugcineni isikhohliwe ukuthi ingabalwa kanjani! Noma kukhona esingakuqondi kahle? Ake sikuthole.
Okokuqala, ake sikhumbule impahla. Njengoba wazi, noma iyiphi inombolo yedesimali inganwetshwa ibe amandla ayishumi. Ngakho, inombolo 123.456 izolingana 1*102 + 2*101 + 3*100 + 4*10-1 + 5*10-2 + 6*10-3. Kodwa ikhompuyutha isebenza ngezinombolo ngefomu kanambambili, ngakho-ke kufanele zimelelwe ngendlela yokwandisa amandla amabili. Ngakho-ke, inombolo engu-5.625 ku-binary imelwe 101.101 futhi izolingana no-1*22 + 0*21 + 1*20 + 1*2-1 + 0*2-2 + 1*2-3. Futhi uma amandla aqondile amabili ehlala enikeza izinombolo zamadesimali eziphelele (1, 2, 4, 8, 16, njll.), ngakho-ke ngezinegethivu yonke into iba nzima kakhulu (0.5, 0.25, 0.125, 0,0625, njll.). Inkinga ukuthi Akuwona wonke amadesimali angamelwa njengengxenye kanambambili enomkhawulo. Ngakho, u-0.1 wethu odume kabi osesimweni sengxenye kanambambili uvela njengenani lezikhathi ezithile elingu-0.0(0011). Ngakho-ke, inani lokugcina lale nombolo kumemori yekhompyutha lizohluka kuye ngokujula kancane.
Manje yisikhathi sokukhumbula ukuthi izinombolo zangempela zigcinwa kanjani kumemori yekhompyutha. Ngokuvamile, inombolo yangempela iqukethe izingxenye ezintathu eziyinhloko - uphawu, i-mantissa kanye ne-exponent. Uphawu lungaba ukuhlanganisa noma ukususa, ngakho ingxenye eyodwa yabelwe yona. Kodwa inani lezicucu ze-mantissa kanye ne-exponent linqunywa uhlobo lwangempela. Ngakho-ke, ohlotsheni lwe-REAL, ubude be-mantissa bungamabhithi angu-23 (ibhithi elilodwa elilingana no-1 lengezwe ngokungaguquki ekuqaleni kwe-mantissa, futhi umphumela ngu-24), futhi i-exponent ingama-bits angu-8. Isamba singamabhithi angu-32, noma amabhayithi angu-4. Futhi ohlotsheni lwe-DOUBLE PRECISION, ubude be-mantissa buzoba amabhithi angu-52, futhi i-eksponenti izoba amabhithi angu-11, isamba samabhithi angu-64, noma amabhayithi angu-8. I-PostgreSQL ayisekeli ukunemba okuphezulu kwezinombolo zamaphuzu antantayo.
Masipakishe inombolo yethu yedesimali engu-0.1 kuzo zombili izinhlobo ze-REAL ne-DOUBLE PRECISION. Njengoba uphawu nenani le-exponent lifana, sizogxila ku-mantissa (ngishiya ngamabomu izici ezingacacile zokugcina amanani we-exponent kanye ne-zero amanani wangempela, ngoba ahlanganisa ukuqonda futhi aphazamise ingqikithi. yenkinga, uma unentshisekelo, bheka izinga le-IEEE 754). Sizotholani? Emgqeni ophezulu ngizonikeza "i-mantissa" yohlobo lwe-REAL (kucatshangelwa ukugoqa okokugcina ngo-1 enombolweni emele eseduze, ngaphandle kwalokho kuyoba ngu-0.099999 ...), futhi emgqeni ophansi - we uhlobo lwe-DOUBLE PRECISION:
0.000110011001100110011001101
0.00011001100110011001100110011001100110011001100110011001
Ngokusobala lezi izinombolo ezimbili ezihluke ngokuphelele! Ngakho-ke, uma uqhathanisa, inombolo yokuqala izofakwa ngoziro futhi, ngakho-ke, izoba nkulu kuneyesibili (kucatshangelwa ukugoqa - leyo ebhalwe ngokugqamile). Lokhu kuchaza ukungaqondakali okuvela ezibonelweni zethu. Esibonelweni sesibili, inombolo ecaciswe ngokucacile engu-0.1 isakazwa ohlotsheni lwe-DOUBLE PRECISION, bese iqhathaniswa nenombolo yohlobo lwe-REAL. Zombili zehliselwa ohlotsheni olufanayo, futhi sinalokhu esikubona ngenhla. Masiguqule umbuzo ukuze yonke into ihambe kahle:
********* ЗАПРОС *********
SELECT 0.1::REAL > 0.1::DOUBLE PRECISION;
**************************
?column?
----------
t
(1 строка)
Futhi ngempela, ngokwenza ukwehlisa kabili inombolo engu-0.1 kuya ku-REAL kanye ne-DOUBLE PRECISION, sithola impendulo yale mfumbe:
********* ЗАПРОС *********
SELECT 0.1::REAL::DOUBLE PRECISION;
**************************
float8
-------------------
0.100000001490116
(1 строка)
Lokhu futhi kuchaza isibonelo sesithathu esingenhla. Inombolo 123 ilula akunakwenzeka ukufaka i-mantissa ibe yizicucu ezingu-24 (23 kucace + 1 kushiwo). Inombolo enkulu engangena kumabhithi angu-24 ngu-224-1 = 16. Ngakho-ke, inombolo yethu engu-777 ifinyezwa ku-215 emelekayo eseduze. Ngokushintsha uhlobo lube DOUBLE PRECISION, asisasiboni lesi simo:
********* ЗАПРОС *********
SELECT 123456789::DOUBLE PRECISION::INT;
**************************
int4
-----------
123456789
(1 строка)
Yilokho kuphela. Kuvele ukuthi azikho izimanga. Kodwa konke okuchazwe kuyisizathu esihle sokucabanga ukuthi uludinga kangakanani uhlobo lwe-REAL. Mhlawumbe inzuzo enkulu yokusetshenziswa kwayo ijubane lokubala ngokulahlekelwa okwaziwayo kokunemba. Kodwa ingabe lesi kungaba yisimo esivamile esingathethelela ukusetshenziswa njalo kwalolu hlobo? Ungacabangi.
Source: www.habr.com