Miksi yleisin kokonaisluku on 32 bittiä, mutta yleisin liukuluku 64 bittiä?

Java- ja C # -taustasta tullessa olen oppinut käyttämään int (32 bittiä) aina, kun tarvitsevat kokonaisluvun, ja double (64 bittiä) murtolukuarvoja käsiteltäessä. Useimmat niiden kehyksistä (JVM ja .NET) odottavat yleensä näitä kahta tyyppiä.

Kysymykseni on, miksi emme käytä johdonmukaisuuteen long ja double? Tiedän, että 64 bittiä tarkkuutta kokonaislukuina ei tarvita suurimman osan ajasta, mutta jälleen kerran, emme yleensä tarvitse 64 bitin tarkkuutta liukulukuina, vai eikö?

Mitä on mahdolliset syyt tähän?

Kommentit

  • ” Se saattaa tuntua kelluvalta riittää siihen, mitä kukaan kohtuudella tarvitsee, mutta se ’ ei … Itse asiassa 64-bittinen kaksinkertaistaa 15 desimaalinumerollaan ’ t tarpeeksi hyvä moniin sovelluksiin … ” ( Miksi tarvitset float / double? )
  • C-taustasta tullessaan olen ’ oppinut käyttämään BigDecimal -kuvia liukulukuihin pyöristämisen ja FP-arvojen vertaaminen on niin ongelmallista.
  • @TMN I ’ en ole varma, että tyyppi, joka heittää, kun yrität laskea 1/3, on ratkaisu aina .

A nswer

Alue vs. tarkkuus

Yksi asia on se, että kyseenalaistan ajatuksen siitä, että yleisin liukuluku käyttää 64-bittistä DPFP (double-precision floating point) -esitystä.

Ainakin suorituskykykriittisessä reaaliajassa Aikakentät, kuten pelit, SPFP (yhden tarkkuuden liukuluku) on edelleen paljon yleisempi, koska likiarvo ja nopeus ovat parempia kuin äärimmäinen tarkkuus.

Ehkä yksi tapa tarkastella tätä on kuitenkin, että 32 -bit int edustaa aluetta 2^32 kokonaislukuja (~ 4,3 miljardia). Yleisin kokonaislukujen käyttö tulee todennäköisesti olemaan indekseinä elementteille, ja se ”on melko terveellinen joukko elementtejä, joita olisi vaikea ylittää ylittämättä nykyisen laitteiston käytettävissä olevaa muistia *.

* Huomaa, että muistissa voi esiintyä virheitä, kun allokoidaan / käytetään yhtä vierekkäistä 4 gigatavun lohkoa jopa 30 gigatavun vapaalla, esim. vierekkäisyyden vuoksi kyseisen lohkon vaatimukset.

32-bittinen kokonaisluku ei ole aina tehokkaampi komentotasolla, mutta se yleensä yleensä tehokkaampi, kun kootaan taulukkoon, esim. koska se vaatii puolet muistista (enemmän indeksejä, jotka mahtuvat yhdelle sivulle / välimuistiriville, esim.).

Huomaa myös, että kuten Lightness Races in Orbit huomauttaa, että ei välttämättä ole edes totta laajasta näkökulmasta, että 32-bittisiä kokonaislukuja käytetään yleisemmin. Minun kapea näkökulmani tulee kentältä, jossa 32-bittinen ints kootaan usein sadoilta tuhansilta miljoonille indekseinä toiseen rakenteeseen – siellä koon puolittaminen voi auttaa erä.

Nyt 64-bittistä DPFP: tä saatetaan käyttää joissakin yhteyksissä paljon enemmän kuin 64-bittisiä kokonaislukuja. Siellä ylimääräiset bitit lisäävät tarkkuus sijasta alue . Monet sovellukset voivat vaatia tarkkuutta tai ainakin paljon helpompaa ohjelmointia erityisen tarkkuudella. Joten luultavasti miksi 64-bittiset DPFP: t saattavat olla yleisempiä kuin 64-bittiset kokonaisluvut joillakin alueilla, ja miksi int saattaa silti olla 32-bittinen monissa skenaarioissa jopa 64-bittisillä alustoilla.

Kommentit

  • I ’ kyseenalaistan idean että yleisin integraalitietotyyppi on myös 32 bittiä, ainakin nykyisin hyödykelaitteistolle kirjoitetuissa ohjelmissa. 64-bittiset käyttöympäristöt ovat nyt niin yleisiä.
  • @I Ke: Epäilen, että monet ohjelmistot käyttävät vain int ja long huolimatta siitä, mikä alue on … Uskon, että tällaiset ohjelmistot käyttävät nykyään pääosin 64-bittisiä kokonaislukuja.
  • Hmm seison korjattu; ilmeisesti int on yleensä edelleen 32-bittinen , suurimmaksi osaksi, jotta vältetään virheiden tuominen juuri sellaiseen koodiin. Ok, olet ’ saanut silti size_t ja long.
  • @LightnessRacesinOrbit Ah Katson, että olen ’ olen erittäin puolueellinen, koska työskentelen usein koodipohjoissa, jotka kokoavat kokonaisluvut johonkin tietorakenteeseen huolestuneena muistin kokonaiskoon suhteen. Yritin tehdä vastauksestani mahdollisimman neutraalin.
  • @I ke: Henkilökohtaisesti teen kaikki tyypini myös erikokoisiksi.Mutta sinä ja minä olemme epäilemättä epänormaaleja. 🙂

Vastaus

No, int ja double ovat Java-asia. Esimerkiksi Objective-C: ssä ja Swiftissä käytettäisiin NSInteger tai Int, joka on 32-bittinen 32-bittisessä koneessa ja 64-bittinen 64-bittisessä koneessa. Tarpeeksi iso laskemaan kaikki muistissa mahdollisesti olevat kohteet. Mikä on ehdottomasti hyödyllistä, on käyttää samaa tyyppiä melkein kaikkialla, ellei tietyssä tilanteessa tarvita jotain muuta.

Java yrittää saada koodin, joka toimii samalla tavalla missä tahansa toteutuksessa, joten heidän mielestään sinun tulisi käyttää samaa tyyppiä riippumatta käyttämästäsi koneesta ja että tyypillä tulisi olla sama määrä bittejä riippumatta kone. Objective-C: llä ja Swiftillä (ja C: llä, C ++: lla myös) on erilainen näkökulma.

Kokonaislukuja käytetään enimmäkseen asioiden laskemiseen, ja yleensä sinulla ei ole niin monta asiaa laskea. Liukulukuinen laskutoimitus tarvitsee tarkkuutta, ja 32-bittinen liukuluku ei usein anna sinulle tarpeeksi tarkkuutta. 64-bittisen kaksoiskäytön käyttö kaikkialla antaa sinulle taistelumahdollisuudet aina riittävän tarkkuuteen olematta kelluvaaritmetiikan asiantuntija. float doesnt ”t.

Mutta mikä sileys antaa sinulle pitkän ja kaksinkertaisen käytön? Kokonaisluvut ja liukuluvut eivät ole sama asia. Niiden bittikoon ei tarvitse olla tasaista. Käytän 2D-pisteitä ja suorakulmioita paljon. Joten yhdenmukaisuuden vuoksi, pitäisikö niiden olla myös 64 bittiä? Pisteitä, joissa on 32 bittiä komponenttia kohden, ja suorakulmioissa, joissa on 16? Tietysti ei. Ei johdonmukaisuutta.

Kommentit

  • Tämä on erittäin hieno vastaus, joka selittää JVM: n puolen pitämällä kunkin tyypin koko samana alustasta riippumatta.

Vastaus

lyhyt, int, yksi ja kaksinkertainen ovat samankokoisia jaavassa kuin ne ovat yleisimmissä C-kääntäjissä 32- ja 64-bittisille alustoille ja C: lle kuten java pitää selvästi int-arvoa tärkeimpänä kokonaislukutyyppinä ja kaksinkertaista päälukukenttätyyppinä. Mielestäni on järkevää sanoa, että Java peri tämän sopimuksen yhteisiltä C-kääntäjiltä tuolloin.

Kokonaisluvut ovat yleensä käytetään c tavaroiden laskeminen tai indeksointi. On melko harvinaista (vaikkakin tuntematonta) tarvetta laskea tai indeksoida jotain yli 2 miljardia. Ennen C99: tä joudut käyttämään toimittajakohtaisia tyyppejä, jos haluat 64-bittisen kokonaisluvun.

Liukulukujen lukuja käytetään yleensä reaalilukujen likiarvona. Yksittäinen tarkkuus on riittävän hyvä suurimman osan ajasta, mutta ei ole vaikea löytää ongelmia, jos se aiheuttaa kohtuuttoman paljon pyöristysvirheitä. Odotan tieteellisen laskennan kysynnän olevan se, mikä ajoi kaksinkertaisen tarkkuuden liukulukutukea yleisesti kauan ennen 64-bittistä kokonaislukutuki oli.

Minusta on mielenkiintoista, että C näyttää kannustavan kaksinkertaisen käyttöä, kun taas fortraani näyttää kannattavan yhden tarkkuuden käyttöä.

Vastaa

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