Às deidh foillseachadh mu fheartan clò-sgrìobhaidh ann am PostgreSQL, bha a’ chiad bheachd mu na duilgheadasan a bhith ag obair le àireamhan fìor. Cho-dhùin mi sùil aithghearr a thoirt air còd nan ceistean SQL a tha rim faighinn dhomh gus faicinn dè cho tric sa chleachdas iad an seòrsa REAL. Tha e a 'tionndadh a-mach gu bheil e air a chleachdadh gu math tric, agus luchd-leasachaidh nach eil an-còmhnaidh a' tuigsinn na cunnartan air a chùlaibh. Agus seo a dh'aindeoin 's gu bheil tòrr math artaigilean air an eadar-lìon agus air Habré mu na feartan a' stòradh àireamhan fìor ann an cuimhne coimpiutair agus mu bhith ag obair còmhla riutha. Mar sin, san artaigil seo feuchaidh mi ri feartan mar seo a chuir an sàs ann am PostgreSQL, agus feuchaidh mi ri sùil aithghearr a thoirt air na duilgheadasan a tha co-cheangailte riutha, gus am bi e nas fhasa do luchd-leasachaidh ceist SQL an seachnadh.
Tha sgrìobhainnean PostgreSQL ag ràdh gu sgiobalta: “Tha riaghladh mhearachdan mar sin agus an iomadachadh aig àm cunntais na chuspair air meur iomlan de matamataig agus saidheans coimpiutaireachd, agus chan eil e air a chòmhdach an seo” (fhad ‘s a tha e gu ciallach a’ toirt iomradh air an leughadair gu inbhe IEEE 754). Dè an seòrsa mhearachdan a thathas a’ ciallachadh an seo? Bruidhnidh sinn riutha ann an òrdugh, agus chan fhada gus am bi e soilleir carson a thog mi am peann a-rithist.
Gabhaidh sinn mar eisimpleir iarrtas sìmplidh:
********* ЗАПРОС *********
SELECT 0.1::REAL;
**************************
float4
--------
0.1
(1 строка)
Mar thoradh air an sin, chan fhaic sinn dad sònraichte - gheibh sinn an 0.1 ris a bheil dùil. Ach a-nis dèanamaid coimeas eadar e agus 0.1:
********* ЗАПРОС *********
SELECT 0.1::REAL = 0.1;
**************************
?column?
----------
f
(1 строка)
Nach co-ionnan! Dè mìorbhuilean! Ach nas fhaide, barrachd. Canaidh cuideigin, tha fios agam gu bheil REAL gad ghiùlan fhèin gu dona le bloighean, agus mar sin cuiridh mi a-steach àireamhan slàn an sin, agus gu cinnteach bidh a h-uile dad gu math leotha. Ceart gu leòr, tilgidh sinn an àireamh 123 gu REAL:
********* ЗАПРОС *********
SELECT 123456789::REAL::INT;
**************************
int4
-----------
123456792
(1 строка)
Agus thionndaidh e a-mach gu bhith 3 a bharrachd! Sin agad e, tha an stòr-dàta air dìochuimhneachadh mu dheireadh mar a bhithear a’ cunntadh! No a bheil sinn a’ mì-thuigse rudeigin? Feuch an dèan sinn a-mach e.
An toiseach, cuimhnichidh sinn an stuth. Mar a tha fios agad, faodar àireamh deicheach sam bith a leudachadh gu cumhachdan de dheich. Mar sin, bidh an àireamh 123.456 co-ionann ri 1 * 102 + 2 * 101 + 3 * 100 + 4 * 10-1 + 5 * 10-2 + 6 * 10-3. Ach tha an coimpiutair ag obair le àireamhan ann an cruth binary, mar sin feumaidh iad a bhith air an riochdachadh ann an cruth leudachadh ann an cumhachdan dhà. Mar sin, tha an àireamh 5.625 ann an binary air a riochdachadh mar 101.101 agus bidh e co-ionann ri 1*22 + 0*21 + 1*20 + 1*2-1 + 0*2-2 + 1*2-3. Agus ma bheir cumhachdan dearbhach dithis an-còmhnaidh àireamhan deicheach slàn (1, 2, 4, 8, 16, msaa), le feadhainn àicheil tha a h-uile dad nas iom-fhillte (0.5, 0.25, 0.125, 0,0625, msaa). Is e an duilgheadas a tha sin Chan urrainnear a h-uile deicheach a riochdachadh mar bhloigh dà-chànanach crìochnaichte. Mar sin, tha an 0.1 cliùiteach againn ann an cruth bloigh dhàna a’ nochdadh mar an luach ràitheil 0.0(0011). Mar thoradh air an sin, bidh luach deireannach na h-àireimh seo ann an cuimhne coimpiutair ag atharrachadh a rèir doimhneachd a’ bhit.
A-nis an t-àm airson cuimhneachadh mar a tha fìor àireamhan air an stòradh ann an cuimhne coimpiutair. San fharsaingeachd, tha trì prìomh phàirtean ann an àireamh fìor - soidhne, mantissa agus neach-aithris. Faodaidh an soidhne a bhith an dàrna cuid plus no minus, agus mar sin tha aon phìos air a riarachadh air a shon. Ach tha an àireamh de phìosan den mantissa agus neach-aithris air a dhearbhadh leis an fhìor sheòrsa. Mar sin, airson an t-seòrsa REAL, is e fad an mantissa 23 pìosan (tha aon rud co-ionann ri 1 air a chur ris gu h-iongantach aig toiseach an mantissa, agus is e an toradh 24), agus is e an neach-aithris 8 pìosan. Is e an àireamh iomlan 32 bit, no 4 bytes. Agus airson an seòrsa DOUBLE PRECISION, bidh fad an mantissa 52 bit, agus bidh an neach-aithris 11 pìosan, airson 64 buillean gu h-iomlan, no 8 bytes. Chan eil PostgreSQL a’ toirt taic do chruinneas nas àirde airson àireamhan puing-fleòdraidh.
Pacaidh sinn an àireamh deicheach 0.1 againn an dà chuid ann an seòrsachan REAL agus DOUBLE PRECISION. Leis gu bheil soidhne agus luach an neach-aithris mar an ceudna, cuiridh sinn fòcas air an mantissa (tha mi a dh’aona ghnothach a’ fàgail às na feartan neo-fhollaiseach ann a bhith a’ stòradh luachan an neach-aithris agus neoni fìor luachan, leis gu bheil iad a’ dèanamh iom-fhillte air tuigse agus a’ tarraing air falbh bhon bhrìgh den duilgheadas, ma tha ùidh agad, faic inbhe IEEE 754). Dè a gheibh sinn? Anns an loidhne gu h-àrd bheir mi am “mantissa” airson an seòrsa REAL (a ’toirt aire do bhith a’ cruinneachadh a ’phìos mu dheireadh le 1 chun àireamh riochdachail as fhaisge, air neo bidh e 0.099999...), agus anns a’ bhun-loidhne - airson an seòrsa PRECISION Dùbailte:
0.000110011001100110011001101
0.00011001100110011001100110011001100110011001100110011001
Gu follaiseach tha iad seo dà àireamh gu tur eadar-dhealaichte! Mar sin, nuair a thathar a 'dèanamh coimeas, bidh a' chiad àireamh air a lìonadh le neamhan agus, mar sin, bidh e nas motha na an dàrna fear (a 'gabhail a-steach cruinneachadh - an tè air a chomharrachadh ann an clò trom). Tha seo a’ mìneachadh na mì-chinnt bho na h-eisimpleirean againn. Anns an dàrna eisimpleir, tha an àireamh ainmichte 0.1 air a thilgeil don t-seòrsa DOUBLE PRECISION, agus an uairsin air a choimeas ri àireamh den t-seòrsa REAL. Tha an dà chuid air an lughdachadh chun aon sheòrsa, agus tha dìreach na chì sinn gu h-àrd againn. Nach atharraich sinn a’ cheist gus an tuit a h-uile càil na àite:
********* ЗАПРОС *********
SELECT 0.1::REAL > 0.1::DOUBLE PRECISION;
**************************
?column?
----------
t
(1 строка)
Agus gu dearbh, le bhith a’ coileanadh lùghdachadh dùbailte den àireamh 0.1 gu REAL agus DOUBLE PRECISION, gheibh sinn am freagairt don tòimhseachan:
********* ЗАПРОС *********
SELECT 0.1::REAL::DOUBLE PRECISION;
**************************
float8
-------------------
0.100000001490116
(1 строка)
Tha seo cuideachd a’ mìneachadh an treas eisimpleir gu h-àrd. Tha an àireamh 123 sìmplidh tha e do-dhèanta am mantissa a chuir a-steach do 24 pìosan (23 soilleir + 1 ri thuigsinn). Is e an t-sreath iomlan as urrainn a dhol a-steach do 24 pìosan 224-1 = 16 Mar sin, tha an àireamh againn 777 cruinn chun an 215 as fhaisge Le bhith ag atharrachadh an seòrsa gu DÙTHCHAS, chan fhaic sinn an suidheachadh seo tuilleadh:
********* ЗАПРОС *********
SELECT 123456789::DOUBLE PRECISION::INT;
**************************
int4
-----------
123456789
(1 строка)
Sin e. Tha e a 'tionndadh a-mach nach eil mìorbhailean. Ach tha a h-uile dad a chaidh a mhìneachadh na adhbhar math airson smaoineachadh air na tha fìor fheum agad air an t-seòrsa REAL. Is dòcha gur e am buannachd as motha a thaobh a bhith ga chleachdadh astar àireamhachadh le call aithnichte de mhearachd. Ach am biodh seo na shuidheachadh uile-choitcheann a bhiodh a’ fìreanachadh cleachdadh cho tric den t-seòrsa seo? Na smaoinich.
Source: www.habr.com
