Izici Ezingezona Zangempela Zezinhlobo Zangempela, noma Qaphela nge-REAL

Ngemva kokushicilelwa izindatshana mayelana nezici zokuthayipha ku-PostgreSQL, ukuphawula kokuqala kwakumayelana nobunzima bokusebenza ngezinombolo zangempela. Nginqume ukubheka ngokushesha ikhodi yemibuzo ye-SQL etholakalayo kimi ukuze ngibone ukuthi basebenzisa kangaki uhlobo lwe-REAL. Kuvela ukuthi isetshenziswa kaningi, futhi abathuthukisi abaqondi ngaso sonke isikhathi izingozi ezingemuva kwayo. Futhi lokhu naphezu kweqiniso lokuthi kunezindatshana eziningi ezinhle ku-inthanethi naku-Habré mayelana nezici zokugcina izinombolo zangempela kumemori yekhompyutha kanye nokusebenza nazo. Ngakho-ke, kulesi sihloko ngizozama ukusebenzisa izici ezinjalo ku-PostgreSQL, futhi ngizozama ukubheka ngokushesha izinkinga ezihlobene nazo, ukuze kube lula kubathuthukisi bemibuzo ye-SQL ukuzigwema.

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

Engeza amazwana