Erinevus ujuki ja topelt vahel - kumba peaksin kasutama?

(Märkus: see artikkel eeldab, et lugejad teavad arvutiteaduse põhitõdesid)

Paljud arvutiteadusesse astujad algajad programmeerijad / tudengid esitavad korduma kippuvaid küsimusi, mis on seotud konkreetse informaatika valdkonnaga, mida nad õpivad. Enamik algajatele mõeldud kursusi algab numbrisüsteemi teemadest, mida kasutatakse tänapäevastes arvutites, sealhulgas binaarne, koma, kaheksajalg ja kuueteistkümnendsüsteemis süsteem. Need on arvunumbrivormingud, mis on arvutites (või kalkulaatorites ja muudes digitaalsetes arvutites) paiknevate numbriliste väärtuste sisemised esitused. Neid väärtusi hoitakse kui “bittide rühmitust”.

Nagu me teame, esindavad arvutid andmeid kahendarvude komplektidena (st. Koos 1 s ja 0s, nagu näiteks, 1111 esindab 15 kümnendsüsteemis) on mõistlik õpetada erinevaid numbrivorminguid, mida kasutatakse dünaamilise väärtuste vahemiku kuvamiseks, kuna need moodustavad arvutamise / numbri töötlemise põhiplokid mis tahes toimingute korral. Kui numbrisüsteem on klassiruumis määratletud (sageli halvasti), on õpilastel kiusatus liikuda sama tüüpi erinevatele numbrivormingutele (s.t.., ujukomaaritmeetiline), millel on teatud täpsus ja arvuvahemik. Seega on nad sunnitud õppima teatud tüüpide vahelisi nüansse. Kaks kõige sagedamini kasutatavat andmetüüpi on Ujuk ja Topelt, ja kuigi nad on suunatud samadele vajadustele (s.t.., ujukomaaritmeetiline), nende sisemises esindatuses ja üldises mõjus programmis arvutamisele on üsna erinev. On kahetsusväärne, et paljud programmeerijad jätavad lameda ja topelt andmetüübi nüansid kahe silma vahele ja kasutavad neid kuritarvitades kohtades, kus neid ei tohiks esmajärjekorras kasutada. Lõpptulemusena tehakse valearvestusi programmi teistes osades.

Selles artiklis räägin teile erinevusest hõljumine ja topelt koodnäidetega C programmeerimiskeeles. Alustame!

Ujuk vs topelt… Mis asi see on?

Ujuk ja topelt on andmeesitus, mida kasutatakse ujukoma aritmeetiliste operatsioonide jaoks, mõelge kümnendarvudele, mille arvute matemaatika klassis, näiteks, 20.123, 16,23, 10,2, jne, nad ei ole täisarvud (st., 2, 5, 15, jne), seega nõuavad nad murdosade arvestamist kahendkoodis. Tulemusena saadud komakohtadena (st., 20.123, 16,23, jne) ei saa tavalise binaarvorminguga (st täisarv) hõlpsasti esitada. Peamine erinevus ujuki ja topelt vahel on see, et esimene on ühe täpsusega (32-bitine) ujukomaandmed, teine ​​aga topelttäpsusega (64-bitine) ujukomaandmetüüp. Topeltit nimetatakse kahekordseks, kuna see on põhimõtteliselt kahekordse täpsusega versioon Floatist. Kui arvutate suurt summat (mõelge tuhandetele 0-le numbris), siis on Doubleis ebatäpsused väiksemad ja te ei kaota palju täpsust.

Parem on töötada välja koodinäidete abil. Järgnev on C-keeles pakutavate matemaatikafunktsioonide abil toiming ujukil ja topelt:

# kaasata

int main ()

ujuk num1 = 1,f / 82;

ujuk num2 = 0;

jaoks (int i = 0; i < 738; ++i)

num2 + = num1;

printf (“%. 7g \ n”, num2);

kahekordne num3 = 1,0 / 82;

kahekordne num4 = 0;

jaoks (int i = 0; i < 738; ++i)

num4 + = num3;

printf (“%. 15g \ n”, number4);

getchar ();

See prindib järgmised andmed:

9.000031

8.99999999999983

Siin näete, et ujuki ja topeltnäitajate täpsuse väike erinevus annab kokku erineva vastuse, ehkki Double näib olevat täpsem kui ujuk.

Järgmine näide sqrt () funktsioonist C-s:

# kaasata

# kaasata

int main ()

ujuk num1 = sqrt (2382719676512365.1230112312312312);

kahekordne num2 = sqrt (2382719676512365.1230112312312312);

printf (“% f \ n”, num1);

printf (“% f \ n”, num2);

getchar ();

See annab järgmise väljundi:

48813108.000000

48813109,678778

Siin näete, et vastus tuplis on täpsem.

Kokkuvõttes on parem kasutada Double'i hõljumiste aritmeetikute jaoks, kuna C-s töötavad mitmed standardsed matemaatikafunktsioonid topeltarvutitel ja tänapäevased arvutid on kahekordse ujukomaga arvutuste jaoks eriti kiired ja tõhusad. See vähendab ujuki kasutamise vajadust, välja arvatud juhul, kui peate kasutama palju ujukoma numbreid (mõelge suurtele massiividele, mille numbrites on tuhandeid 0-numbrit) või kui kasutate süsteemi, mis ei toeta topelt- täpne ujukoma, kuna paljud GPU-d, vähese energiatarbega seadmed ja teatud platvormid (ARM Cortex-M2, Cortex-M4 jne) ei toeta veel Double-i, siis peaksite kasutama hõljumist. Lisaks tuleb meeles pidada, et teatud GPU / CPU töötavad float-töötlusel paremini / tõhusamalt, näiteks vektorite / maatriksi arvutamisel, nii et peate võib-olla otsima riistvara spetsifikatsiooni käsiraamatut / dokumentatsiooni, et paremini otsustada, millist neist peaksite kasutama konkreetse masina jaoks.

Kaasaegseid arvuteid sihtivas koodis on harva põhjust kasutada topelt asemel ujukit. Doublei lisatäpsus vähendab, kuid ei välista ümardamisvigade või muude ebatäpsuste võimalust, mis võib põhjustada probleeme muudes programmi osades. Paljud matemaatikafunktsioonid või operaatorid teisendavad ja tagastavad topelt, nii et te ei pea numbreid tagasi floatisse tagasi tooma, kuna see võib täpsust kaotada. Ujuvapunktiga aritmeetika üksikasjaliku analüüsi jaoks soovitan tungivalt lugeda seda vinge artiklit (http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html).

Kokkuvõte

Niisiis… lühidalt:

Kohad, kus peaksite Floatit kasutama:

  • Kui sihite riistvara, kus ühe täpsusega on kiiremini kui kahe täpsusega.
  • Teie rakendus kasutab palju ujukoma aritmeetikat, näiteks tuhandeid numbreid tuhandete 0-ga.
  • Teete optimeerimist väga madalal tasemel. Näiteks kasutate spetsiaalseid protsessori juhiseid (st SSE, SSE2, AVX jne), mis töötavad korraga mitmel arvul / massiivil / vektoril.

Järeldus

Selles artiklis olen rõhutanud erinevust ujuki ja topelt vahel ning seda, kumba tuleks konkreetsetes kohtades kasutada. Väidetavalt on parem kasutada Doubleit enamikus kohtades pimesi, eriti kui sihite tänapäevaseid arvuteid, kuna kahekordse ujukomaaritmeetri kasutamisest tulenev vähese efektiivsuse võimalus on ebatõenäoline. Kui teil on küsimusi, küsige seda allpool olevas kommentaaride jaotises!