Usein ohjelmointikokemuksessani minun on tehtävä päätös, pitäisikö minun käyttää floatia tai doubleia todelliseen käyttöön numerot. Joskus menen kellumaan, joskus kaksinkertaiseen, mutta tämä tuntuu subjektiivisemmalta. Jos joutuisin puolustamaan päätöstäni, en luultavasti esittäisi järkeviä syitä.

Milloin käytät kellua ja milloin kaksinkertaista? Käytätkö aina kaksinkertaista, vain kun muistirajoitukset ovat olemassa, menet kellumaan? Tai käytät aina kellua, ellei tarkkuusvaatimus vaadi kaksinkertaista käyttöä? Onko kelluvan ja kaksinkertaisen välillä aritematiikan laskennallisessa monimutkaisuudessa eroja? Mitkä ovat float- tai double-käytön edut ja haitat? Ja oletko käyttänyt edes pitkää kaksinkertaista?

Kommentit

  • Monissa tapauksissa et halua käyttää kumpikaan, vaan desimaalinen kelluva tai kiinteän pisteen tyyppi. Binaariset liukulukutyypit ’ t eivät voi edustaa suurinta osaa desimaaleista.
  • Liittyy kohtaan Mikä aiheuttaa liukulukujen pyöristysvirheitä ? . @CodesInChaos vastauksessani siellä ehdotetaan resursseja, jotka auttavat sinua tekemään tämän päätöksen, kaikille sopivia ratkaisuja ei ole.
  • Mitä tarkalleen tarkoitat ” desimaaleilla ”. Jos sinun on esitettävä tarkasti arvot, kuten 0,01 (esimerkiksi rahalle), (binääri) liukuluku ei ole vastaus. Jos tarkoitat vain ei-kokonaislukuja, liukuluku on todennäköisesti ok – mutta silloin ” desimaalit ” ei ole paras sana kuvaamaan tarvitsemasi.
  • Ottaen huomioon (nykyään), että suurin osa näytönohjaimista hyväksyy uimurit kaksinkertaisiksi, grafiikan ohjelmointi käyttää usein yhtä tarkkuutta.
  • Et ’ ei ole aina valinnanvaraa. Esimerkiksi Arduino-alustalla sekä kaksinkertainen että kelluva vastaavat kellua. Sinun on löydettävä lisäosakirjasto todellisten kaksinkertaistusten käsittelemiseksi.

Vastaa

Oletusvalinta liukuluku-tyypin tulee olla double. Tämä on myös tyyppi, jonka saat liukulukuisten literaalien kanssa ilman loppuliitettä tai (C: ssä) vakiotoimintoja, jotka toimivat liukulukuilla (esim. exp, sin jne.).

float tulisi käyttää vain, jos sinun on käytettävä paljon liukulukuja (ajattele tuhannen tai enemmän) ja algoritmin analyysi on osoittanut, että pienennetty alue ja tarkkuus eivät aiheuta ongelmaa.

long double voidaan käyttää, jos tarvitset enemmän etäisyyttä tai tarkkuutta kuin double, ja jos se tarjoaa tämän kohdealustallasi.

Yhteenvetona: float ja long double tulisi varata asiantuntijoiden käyttöön, ja double pitäisi käyttää joka päivä.

Kommentit

  • En todennäköisesti harkitsisi kellua muutaman tuhannen arvon kohdalla, ellei liukuluku-välimuistiin liittyisi suorituskykyongelmia g ja tiedonsiirto. Analyysin suorittaminen maksaa yleensä huomattavia kustannuksia osoittaakseen, että float on riittävän tarkka.
  • Lisäaineena voi olla hyödyllistä käyttää samoja tietotyyppejä, jos tarvitset yhteensopivuutta muiden järjestelmien kanssa.
  • I ’ käytin kellukkeita miljoonille numeroille, ei 1000: lle. Jotkut GPU: t pärjäävät paremmin uimureiden kanssa, jolloin erikoistapauksissa käytetään uimureita. Muuten, kuten sanot, käytä kaksinkertaisia.
  • @PatriciaShanahan – ’ suorituskykyongelma, joka liittyy .. ’ A hyvä esimerkki on, jos aiot käyttää SSE2: ta tai vastaavia vektoriohjeita, voit tehdä 4 opsia / vektoria floatissa (vs. 2 per tupla), mikä voi parantaa merkittävästi nopeutta (puolet niin monta opsia ja puolet niin paljon tietoa lukea & kirjoita). Tämä voi merkittävästi laskea kynnystä, jos kellukkeiden käytöstä tulee houkutteleva, ja vaivan arvoista on selvittää numeeriset kysymykset.
  • Kannatan tätä vastausta yhdellä lisävinkillä: Kun näytöllä käytetään RGB-arvoja, se on hyväksyttävää käyttää float (ja joskus puolitarkkuutta), koska ihmissilmällä, näytöllä tai värijärjestelmällä ei ole niin paljon tarkkuutta. Tämä neuvo soveltuu esimerkiksi OpenGL: ään jne. Tämä lisäneuvo ei koske lääketieteellisiä kuvia, joiden tarkkuusvaatimukset ovat tiukemmat.

Vastaa

Moderniin tietokoneisiin kohdistetussa koodissa on harvoin syytä käyttää kelluketta kaksoiskoodin sijaan. Ylimääräinen tarkkuus vähentää (mutta ei poista) pyöristysvirheiden tai muiden epätarkkuuksien mahdollisuutta, jotka aiheuttavat ongelmia.

Tärkeimmät syyt, joiden vuoksi voin ajatella floatin käyttöä, ovat:

  1. Tallennat suuria numeroita ja sinun on vähennettävä ohjelmasi muistin kulutusta.
  2. Kohdistat järjestelmään, joka ei tue luonnollisesti kaksitarkkuista liukulukua. Viime aikoihin asti monet näytönohjaimet tukivat vain yksittäisiä tarkkoja liukupisteitä. Olen varma, että on paljon pienitehoisia ja upotettuja prosessoreita, joilla on myös rajoitettu liukuluku.
  3. Kohdistat laitteistoon, jossa yksi tarkkuus on nopeampi kuin kaksoistarkkuus, ja sovelluksesi käyttää paljon Uskon, että kaikki nykyaikaiset Intel-suorittimet suorittavat kaksinkertaisen tarkkuuden, joten et saa mitään tässä.
  4. Teet matalan tason optimointia esimerkiksi käyttämällä erityisiä suorittimen ohjeita, jotka toimivat useilla numeroilla kerrallaan.

Joten periaatteessa kaksinkertainen tapa on tapa mene, ellei sinulla ole laitteistorajoituksia tai ellei analyysi ole osoittanut, että kaksinkertaisten tarkkuuslukujen tallentaminen edistää merkittävästi muistin käyttöä.

Kommentit

  • ” Nykyaikaiset tietokoneet ” tarkoittavat Intel x86 -prosessoreita. Jotkut muinaisten käyttämistä koneista tarjosivat täydellisen riittävän tarkkuuden perus kelluketyypin kanssa. (CDC 6600 käytti 60-bittistä sanaa, 48 bittiä normalisoitua liukulantamantissaa, 12 bittiä eksponenttia. Se ’ on melkein mitä x86 antaa sinulle kaksinkertaisen tarkkuuden.)
  • @ John.R.Strohm: sopinut, mutta CD-kääntäjiä ei ollut CDC6600: lla. Se oli Fortran IV …
  • ” nykyaikaisilla tietokoneilla ” tarkoitan mitä tahansa viime vuosikymmenellä rakennettua prosessoria tai kaksi, tai oikeastaan, koska IEEE: n liukulukustandardi pantiin laajasti täytäntöön. ’ Olen täysin tietoinen siitä, että muita kuin x86 -arkkitehtuureja on olemassa, ja pidin tämän mielessä vastauksessani – mainitsin GPU: t ja sulautetut prosessorit, jotka eivät yleensä ole x86.
  • Se ’ ei kuitenkaan yksinkertaisesti ole totta. SSE2 pystyy käsittelemään 4 kelluketta tai 2 tuplaa yhdellä kertaa, AVX voi käsitellä 8 kellua tai 4 tuplaa, AVX-512 voi käsitellä 16 kellua tai 8 tuplaa. Kaikenlaisessa korkean suorituskyvyn tietojenkäsittelyssä kelluvien matematiikan tulisi ajatella olevan kaksinkertainen samojen operaatioiden nopeuteen verrattuna kaksinkertaistamiseen x86: lla.
  • Ja se ’ s jopa pahempaa kuin se, koska prosessorin välimuistiin mahtuu kaksi kertaa niin paljon kelluvia kuin kaksinkertaistuu, ja muistiviive on todennäköisesti tärkein pullonkaula monissa ohjelmissa. Koko toimivan uimurijoukon pitäminen välimuistissa voi olla kirjaimellisesti suuruusluokkaa nopeampi kuin kaksinkertaistaminen ja niiden vuotaminen RAM-muistiin.

Vastaa

Käytä double kaikkia laskelmia ja lämpötilamuuttujia. Käytä float, kun sinun on ylläpidettävä joukko numeroita – float[] (jos tarkkuus on riittävä), ja olet tekemisissä yli kymmenien tuhansia float numeroita.

Monet / useimmat matemaattiset funktiot tai operaattorit muuntavat / palauttavat double, ja sinä et ” Et halua lähettää numeroita takaisin osioon float mahdollisten välivaiheiden osalta.

Esim. jos syötät 100 000 numeroa tiedostosta tai virrasta ja sinun on lajittele ne, laita numerot float[] -kohtaan.

Vastaa

Jotkut alustat (ARM Cortex-M2, Cortex-M4 jne.) Älä tue double (Se voidaan aina tarkistaa käyttöoppaasta Jos kääntämisvaroituksia tai -virheitä ei ole, se ei tarkoita, että koodi on paras. double voidaan jäljitellä .). Siksi joudut ehkä pitämään kiinni int tai kelluvasta .

Jos näin ei ole, käytän double .

Voit tarkistaa kuuluisan D. Goldbergin artikkelin (”Mitä jokaisen tietojenkäsittelytieteen tutkijan tulisi tietää liukulukulaskennasta”). Sinun tulisi miettiä kahdesti, ennen kuin käytät liukulukuaritmeettista. On melko suuri mahdollisuus, että niitä ei tarvita lainkaan omassa tilanteessasi.

http://perso.ens-lyon.fr/jean-michel.muller/goldberg.pdf

kommentit

  • Tähän kysymykseen vastattiin jo melko hyvin vuosi sitten …mutta joka tapauksessa sanon, että ’ sanon aina, kun ’ käytät kaksoislaitetta alustoilla, joissa on kaksinkertainen tarkkuus FPU-kiihdytys, sinun tulisi käyttää se muilla, vaikka se merkitsisikin kääntäjän antamista jäljitellä sen sijaan, että hyödynnettäisiin vain liukulukuista FPU: ta (huomaa, että FPU ’ eivät ole ’ ei vaadita myöskään kaikilla alustoilla, itse asiassa Cortex-M4 -arkkitehtuuri määrittelee ne valinnaiseksi ominaisuudeksi [oli M2 kirjoitusvirhe?]).
  • Tämän logiikan avain on sen ’ tosi pitäisi olla uupunut liukulukuaritmeettisuudesta, ja se ’ s monta ” quirks ”, ehdottomasti ei pidä FPU-tuen olemassaoloa kaksinkertaistamiseen tarkoittaen yksinkertaisesti tuplan käyttämistä kellukkeiden sijaan. Kellukkeet ovat yleensä nopeampia kuin kaksinkertaiset ja vievät vähemmän muistia (FPU-ominaisuudet vaihtelevat). Käytön määrä estää tämän kohdan optimoinnin ennenaikaisesti. Kuten tosiasiat kaksinkertaistuvat, ovat selvästi ylivoimaisia monissa (ehkä jopa useimmissa) sovelluksissa. Täytyykö tämän sivun elementtien suhteellinen sijainti ja koko laskea 13 desimaalin tarkkuudella?
  • Kun lisäät linkin sivuston ulkopuolelle olevalle sivulle tai asiakirjaan, kopioi asiaankuuluvat tiedot tai yhteenveto asiakirjasta vastaukseesi. Verkkosivuston ulkopuolisilla linkeillä on taipumus hävitä ajan myötä.

Vastaus

Todellisessa maailmassa esiintyvien ongelmien kohdalla näytteenottokynnys on tietosi ovat tärkeitä vastaettaessa tähän kysymykseen. Samoin melulattia on myös tärkeä. Jos tietotyyppivalinta ylittää jommankumman, tarkkuuden lisääntymisestä ei ole hyötyä.

Useimmat reaalimaailman samplerit ovat rajoitettuja 24-bittisiin DAC: iin. Ehdotetaan, että 32 bitin tarkkuuden tosielämän laskelmissa pitäisi olla riittävä, jos merkitsevyys on 24 bittiä tarkkuutta.

Kaksinkertainen tarkkuus maksaa kaksinkertaisen muistin. Siksi kaksinkertaisen käytön rajoittaminen kellukkeiden yli voi vähentää huomattavasti käynnissä olevien sovellusten muistin jalanjälkeä / kaistanleveyttä.

Vastaa

Valinta mitä muuttujaa float- ja double-arvojen välillä käytetään, riippuu vaadittujen tietojen tarkkuudesta. Jos vastaukselta vaaditaan vähäinen ero todellisesta vastauksesta, vaadittavien desimaalien lukumäärä on monta, joten sanotaan, että kaksinkertainen on käytössä. Float pilkkoo osan desimaaliosista ja vähentää tarkkuutta.

Kommentit

  • Tämä vastaus ei ’ lisää kysymykseen mitään uutta ja ei sano mitään todellisesta käytöstä.

Vastaa

Käytän yleensä tyyppiä float, kun En tarvitse paljon tarkkuutta – esimerkiksi rahalle – mikä on väärin, mutta mitä olen tottunut väärin.

Toisaalta käytän double kun tarvitsen enemmän tarkkuutta, esimerkiksi monimutkaisille matemaattisille algoritmeille.

C99-standardi sanoo tämän:

Liukulukutyyppejä on kolme: kelluva, kaksinkertainen ja pitkä kaksinkertainen. Tyyppikakku tarjoaa vähintään yhtä paljon tarkkuutta kuin kelluva, ja tyypin pitkä tuplakakku tarjoaa vähintään yhtä paljon tarkkuutta kuin kaksinkertainen. Tyypin kelluvan arvojoukko on osajoukko tyypin kaksinkertainen arvojoukko; double-tyypin arvojoukko on osajoukko tyypin long double arvoryhmästä.

En ole koskaan käyttänyt long double, mutta en käytä C / C ++: ta niin paljon. Yleensä käytän dynaamisesti kirjoitettuja kieliä, kuten Python, joissa sinun ei tarvitse huolehtia tyyppeistä.

Lisätietoja Double vs Float : sta on kohdassa tämä kysymys SO: ssa .

Kommentit

  • Liukuluvun käyttäminen vakavissa rahalaskelmissa on todennäköisesti virhe.
  • float on täsmälleen väärä rahatyyppi. Sinun on käytettävä suurinta mahdollista tarkkuutta.
  • @BartvanIngenSchenau Rahan liukuluku on yleensä kunnossa, binaarinen liukuluku ei. Esimerkiksi .net ’ s Decimal on liukuluku ja se tyypillisesti ’ s hyvä valinta rahalaskelmiin.
  • @ChrisF Et tarvitse ’ et tarvitse ” tarkkuutta ” rahaa varten tarvitset tarkat arvot.
  • @SeanMcSomething – reilu piste. Kellukkeet ovat kuitenkin edelleen väärä tyyppi, ja kun otetaan huomioon useimmilla kielillä käytettävissä olevat liukulukutyypit, tarvitset ” tarkkaa ” saadaksesi ” tarkat arvot ”.

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *