Likarolo tseo e seng tsa 'Nete tsa Mefuta ea Sebele, kapa E-ba hlokolosi ka SEBELE

Kamora ho hatisoa Lingoloa mabapi le likarolo tsa ho thaepa ho PostgreSQL, maikutlo a pele a ne a le mabapi le mathata a ho sebetsa ka linomoro tsa 'nete. Ke nkile qeto ea ho shebisisa khoutu ea lipotso tsa SQL tse fumanehang ho nna ho bona hore na ba sebelisa mofuta oa REAL hangata hakae. Hoa fumaneha hore e sebelisoa hangata, mme ha se kamehla bahlahisi ba utloisisang likotsi tsa eona. 'Me sena se sa tsotellehe taba ea hore ho na le lingoliloeng tse ngata tse ntle Inthaneteng le ho Habré mabapi le likarolo tsa ho boloka linomoro tsa' nete mohopolong oa k'homphieutha le ho sebetsa le tsona. Ka hona, sehloohong sena ke tla leka ho sebelisa likarolo tse joalo ho PostgreSQL, 'me ke tla leka ho sheba ka potlako mathata a amanang le bona, e le hore ho tla ba bonolo ho baetsi ba lipotso tsa SQL ho li qoba.

Litokomane tsa PostgreSQL li bua ka mokhoa o hlakileng: "Taolo ea liphoso tse joalo le phatlalatso ea tsona nakong ea lipalo ke taba ea lekala lohle la lipalo le mahlale a khomphutha, 'me ha e akaretsoe mona" (ha a ntse a bua ka bohlale ho 'mali ho IEEE 754 standard). Ke liphoso tsa mofuta ofe tse boleloang moo? A re buisaneng ka tsona ka tatellano, ’me haufinyane ho tla hlaka hore na ke hobane’ng ha ke ile ka nka pene hape.

Ha re nke mohlala ka kopo e bonolo:

********* ЗАПРОС *********
SELECT 0.1::REAL;
**************************
float4
--------
    0.1
(1 строка)

Ka lebaka leo, re ke ke ra bona letho le ikhethang - re tla fumana 0.1 e lebelletsoeng. Empa joale a re e bapise le 0.1:

********* ЗАПРОС *********
SELECT 0.1::REAL = 0.1;
**************************
?column?
----------
f
(1 строка)

Ha e lekane! Ke mehlolo e kakang! Empa ho feta moo, ho feta. E mong o tla re, kea tseba hore REAL e itšoara hampe ka likaroloana, kahoo ke tla kenya linomoro tse feletseng moo, 'me ntho e' ngoe le e 'ngoe e tla ba hantle le bona. Ho lokile, ha re lahleleng nomoro ea 123 ho REAL:

********* ЗАПРОС *********
SELECT 123456789::REAL::INT;
**************************
   int4   
-----------
123456792
(1 строка)

'Me e ile ea e-ba tse ling tse 3! Ke eona, database e se e lebetse ho bala! Kapa na ho na le ntho eo re sa e utloisiseng? Ha re e utloisise.

Pele, a re hopoleng thepa. Joalo ka ha u tseba, palo efe kapa efe ea decimal e ka atolosoa ho ba matla a leshome. Kahoo, palo 123.456 e tla lekana le 1*102 + 2*101 + 3*100 + 4*10-1 + 5*10-2 + ​​6*10-3. Empa k'homphieutha e sebetsa ka linomoro ka mokhoa oa binary, kahoo li tlameha ho emeloa ka mokhoa oa ho atolosa matla a mabeli. Ka hona, palo ea 5.625 ka binary e emeloa e le 101.101 'me e tla lekana le 1*22 + 0*21 + 1*20 + 1*2-1 + 0*2-2 + 1*2-3. 'Me haeba matla a mabeli a fana ka linomoro tse feletseng (1, 2, 4, 8, 16, joalo-joalo), joale ka tse mpe ntho e 'ngoe le e' ngoe e rarahane le ho feta (0.5, 0.25, 0.125, 0,0625, joalo-joalo). Bothata ke hore Ha se decimal e 'ngoe le e' ngoe e ka hlahisoang e le karoloana e lekanyelitsoeng ea binary. Ka hona, 0.1 ea rona e tummeng hampe ka mokhoa oa karoloana ea binary e hlaha e le boleng ba nakoana 0.0 (0011). Ka lebaka leo, boleng ba ho qetela ba nomoro ena mohopolong oa komporo bo tla fapana ho latela botebo ba hanyane.

Hona joale ke nako ea ho hopola kamoo linomoro tsa sebele li bolokiloeng mohopolong oa khomphuta. Ka kakaretso, palo ea sebele e na le likarolo tse tharo tse kholo - letšoao, mantissa le exponent. Letšoao e ka ba ho eketsa kapa ho tlosa, kahoo ho fanoe ka karolo e le 'ngoe bakeng sa lona. Empa palo ea likotoana tsa mantissa le exponent e khethoa ke mofuta oa 'nete. Kahoo, bakeng sa mofuta oa SEBELE, bolelele ba mantissa ke li-bits tse 23 (karolo e le 'ngoe e lekanang le 1 e kenyellelitsoe ka mokhoa o hlakileng qalong ea mantissa,' me sephetho ke 24), 'me motsoako ke likotoana tse 8. Kakaretso ke li-bits tse 32, kapa li-byte tse 4. 'Me bakeng sa mofuta oa DOUBLE PRECISION, bolelele ba mantissa e tla ba likotoana tse 52,' me exponent e tla ba li-bits tse 11, bakeng sa kakaretso ea 64 bits, kapa 8 byte. PostgreSQL ha e tšehetse ho nepahala ho holimo bakeng sa linomoro tsa lintlha tse phaphametseng.

Ha re ke re kenye nomoro ea rona ea decimal 0.1 mefuteng ea REAL le DOUBLE PRECISION ka bobeli. Kaha lets'oao le boleng ba exponent li ts'oana, re tla tsepamisa maikutlo ho mantissa (ke tlohela ka boomo likarolo tse sa bonahaleng tsa ho boloka boleng ba boleng ba exponent le zero, kaha li thatafatsa kutloisiso le ho sitisa moelelo oa taba. ea bothata, haeba u thahasella, bona maemo a IEEE 754). Re tla fumana eng? Moleng o ka holimo ke tla fana ka "mantissa" bakeng sa mofuta oa SEBELE (ho nahanne ka ho pota-pota ha karolo ea ho qetela ka 1 ho ea ho nomoro e haufi e emelang, ho seng joalo e tla ba 0.099999 ...), le ka tlase - bakeng sa mofuta oa DOUBLE PRECISION:

0.000110011001100110011001101
0.00011001100110011001100110011001100110011001100110011001

Ho hlakile hore tsena ke lipalo tse peli tse fapaneng ka ho felletseng! Ka hona, ha ho bapisoa, palo ea pele e tla kenngoa ka zero, ka hona, e tla ba kholo ho feta ea bobeli (ho nahanoa ka ho pota-pota - e tšoailoeng ka mongolo o motenya). Sena se hlalosa ho se hlaka ho tsoa mehlaleng ea rona. Mohlala oa bobeli, nomoro e boletsoeng ka ho hlaka 0.1 e lahleloa mofuteng oa DOUBLE PRECISION, ebe e bapisoa le palo ea mofuta oa REAL. Ka bobeli li fokotsehile mofuteng o le mong, 'me re na le hantle seo re se bonang ka holimo. Ha re fetole potso hore tsohle li tsamaee hantle:

********* ЗАПРОС *********
SELECT 0.1::REAL > 0.1::DOUBLE PRECISION;
**************************
?column?
----------
t
(1 строка)

'Me ka sebele, ka ho fokotsa palo ea 0.1 habeli ho ea ho REAL le DOUBLE PRECISION, re fumana karabo ea selotho:

********* ЗАПРОС *********
SELECT 0.1::REAL::DOUBLE PRECISION;
**************************

      float8       
-------------------
0.100000001490116
(1 строка)

Sena se boetse se hlalosa mohlala oa boraro o ka holimo. Nomoro ea 123 e bonolo ha ho khonehe ho kenya mantis ka likotoana tse 24 (23 e hlakileng + 1 e bolela). Palo e felletseng e ka fellang likotong tse 24 ke 224-1 = 16. Ka hona, palo ea rona 777 e pota-potiloe ho e haufi e emelang 215. Ka ho fetola mofuta ho DOUBLE PRECISION, ha re sa bona boemo bona:

********* ЗАПРОС *********
SELECT 123456789::DOUBLE PRECISION::INT;
**************************
   int4   
-----------
123456789
(1 строка)

Ke phetho. Hoa fumaneha hore ha ho na mehlolo. Empa ntho e 'ngoe le e' ngoe e hlalositsoeng ke lebaka le utloahalang la ho nahana hore na u hlile u hloka mofuta oa SEBELE hakae. Mohlomong molemo o moholo ka ho fetisisa oa tšebeliso ea eona ke lebelo la lipalo ka tahlehelo e tsebahalang ea ho nepahala. Empa na see e ka ba boemo bo akaretsang bo ka lokafatsang tšebeliso e joalo khafetsa ea mofuta oo? O seke wa nahana.

Source: www.habr.com

Eketsa ka tlhaloso