De ce este cel mai comun număr întreg 32 de biți, dar cel mai frecvent număr în virgulă mobilă 64 de biți?

Venind dintr-un fundal Java și C #, am învățat să folosesc int (32 de biți) ori de câte ori am au nevoie de un număr întreg și double (64 biți) când se ocupă de valori fracționare. Majoritatea metodelor din cadrele respective (JVM și .NET) așteaptă de obicei aceste două tipuri.

Întrebarea mea este, de ce nu folosim atât long, cât și double pentru consistență? Știu că a avea 64 de biți de precizie în numere întregi nu este nevoie de cele mai multe ori, dar din nou, nu avem nevoie de 64 de biți de precizie în numerele cu virgulă mobilă sau nu?

Ce este raționamentul din spatele acestui lucru, dacă există?

Comentarii

  • ” S-ar putea să pară că un float ar fi să fie suficient pentru ceea ce oricine ar avea în mod rezonabil nevoie, dar nu ‘ nu … De fapt, dublurile pe 64 de biți cu cele 15 cifre zecimale ale acestora nu sunt ‘ t suficient de bun pentru multe aplicații … ” ( De ce ai nevoie de float / double? )
  • Venind dintr-un fundal C, am ‘ am învățat să folosesc BigDecimal pentru numerele cu virgulă mobilă, de la rotunjire și compararea valorilor FP este atât de problematică.
  • @TMN Nu ‘ nu sunt sigur că un tip care se aruncă atunci când încercați să calculați 1/3 este soluția pentru toate .

A nswer

Gama vs. Precizie

Un lucru este că aș contesta ideea că cel mai obișnuit număr în virgulă mobilă utilizează o reprezentare DPFP pe 64 de biți (virgulă cu dublă precizie).

Cel puțin în performanță critică reală câmpuri de timp, cum ar fi jocurile, SPFP (virgulă mobilă cu o singură precizie) este încă mult mai frecventă, deoarece aproximarea și viteza acolo sunt de preferat până la cea mai mare precizie.

Cu toate acestea, probabil că o modalitate de a privi acest lucru este aceea că -bit int reprezintă un interval de 2^32 numere întregi (~ 4,3 miliarde). Cea mai obișnuită utilizare a numerelor întregi va fi probabil ca indici pentru elemente și că „o gamă destul de sănătoasă de elemente care ar fi greu de depășit fără a depăși memoria disponibilă cu hardware-ul * de astăzi.

* Rețineți că pot apărea erori de memorie atunci când alocați / accesați un singur bloc contiguu de 4 gigaocteți chiar și cu 30 gigaocteți liber, de exemplu, din cauza contiguității cerințele acelui bloc.

Un întreg pe 32 de biți nu este întotdeauna mai eficient la nivelul instrucțiunilor, dar este tinde să fie în general mai eficient atunci când este agregat într-o matrice, de exemplu, deoarece necesită jumătate din memorie (mai mulți indici care se pot încadra într-o singură linie de pagină / cache, de exemplu).

De asemenea, rețineți că, ca Lightness Races in Orbit subliniază, nu este neapărat nici măcar adevărat dintr-o perspectivă largă că numerele întregi de 32 de biți sunt mai frecvent utilizate. Am perspectiva mea îngustă care vine dintr-un câmp în care 32 de biți ints sunt adesea agregate cu sute de mii până la milioane ca indici într-o altă structură – acolo reducerea la jumătate poate ajuta la o lot.

Acum DPFP pe 64 de biți ar putea să fie folosit cu mult mai mult decât numere întregi pe 64 de biți în anumite contexte. Acolo, biții suplimentari adaugă precizie mai degrabă decât interval . O mulțime de aplicații pot solicita precizie sau cel puțin au o programare de timp mult mai ușoară cu o precizie suplimentară disponibilă. Așadar, probabil de ce DPFP-urile pe 64 de biți ar putea să fie mai frecvente decât numerele întregi pe 64 de biți în unele zone și de ce int ar putea fi în continuare 32 de biți în multe scenarii chiar și pe platforme pe 64 de biți.

Comentarii

  • Am ‘ contest ideea că cel mai obișnuit tip de date integrale are o lățime de 32 de biți, cel puțin în programele scrise astăzi pe hardware de marfă. Platformele pe 64 de biți sunt atât de răspândite acum.
  • @I Ke: Lucrul este că bănuiesc că multe programe utilizează doar int și long fără să-i pese cu adevărat care este gama … și un astfel de software este, cred, în principal, folosind numere întregi pe 64 de biți în ambele cazuri în zilele noastre.
  • Hmm Stau corectat; aparent int este în general încă pe 32 de biți , în mare măsură pentru a evita introducerea de bug-uri doar în acel tip de cod. Ok, bine ‘ ai primit încă size_t și long.
  • @LightnessRacesinOrbit Ah, văd, sunt ‘ extrem de părtinitor, deoarece lucrez deseori în baze de coduri care agregă numere întregi într-o anumită structură de date, cu îngrijorare asupra dimensiunii totale a memoriei. Am încercat să-mi fac răspunsul cât mai neutru posibil.
  • @I ke: Personal îmi creez și toate tipurile în mod explicit.Dar tu și cu mine suntem, fără îndoială, anormali. 🙂

Răspuns

Ei bine, int și double este un lucru Java. De exemplu, în Objective-C și Swift ați utiliza NSInteger sau Int, care este pe 32 de biți pe o mașină de 32 de biți și pe 64 de biți pe o mașină de 64 de biți. Suficient de mare pentru a număra orice număr de articole care ar putea fi în memorie. Ceea ce este cu siguranță util este să folosiți același tip aproape peste tot, cu excepția cazului în care într-o anumită situație aveți nevoie de altceva.

Java încearcă să aibă cod care rulează la fel la orice implementare, așa că consideră că ar trebui să utilizați același tip independent de mașina pe care o utilizați și că tipul ar trebui să aibă același număr de biți independent de Mașina. Objective-C și Swift (și C, C ++, de asemenea) au un punct de vedere diferit.

Numerele întregi sunt utilizate mai ales pentru numărarea lucrurilor și, de obicei, nu aveți atâtea lucruri de numărat. Aritmetica în virgulă mobilă are nevoie de precizie, iar virgula mobilă pe 32 de biți nu vă oferă de multe ori suficientă precizie. Folosind dublu pe 64 de biți oriunde vă oferă șansa de luptă de a avea întotdeauna suficientă precizie, fără a fi un specialist în aritmetică în virgulă mobilă. float nu este.

Dar ce consistență ți-ar oferi utilizarea lungă și dublă? Numerele întregi și numerele în virgulă mobilă nu sunt același lucru. Nu este nevoie ca acestea să aibă o dimensiune de biți consistentă. Folosesc puncte 2D și dreptunghiuri mult. Deci, pentru consistență, ar trebui să fie, de asemenea, 64 de biți? Puncte cu 32 de biți pe componentă și dreptunghiuri cu 16? Desigur că nu. Nu este necesară consistență.

Comentarii

  • Acesta este un răspuns foarte frumos care explică partea JVM a acestuia de a păstra dimensiunea fiecărui tip la fel, indiferent de platformă.

Răspuns

short, int, single și double au aceeași dimensiune în java ca în cele mai comune compilatoare C pentru platformele pe 32 și 64 de biți și C ca java consideră clar că int este principalul tip întreg și dublu ca tip principal cu virgulă mobilă. Cred că este rezonabil să spunem că Java a moștenit această convenție de la compilatoarele C obișnuite la acel moment. folosit pentru c numărătoare sau indexare a lucrurilor. Este destul de rar (deși nu se aude nemaiauzit) să trebuiască să numeri sau să indexezi mai mult de 2 miliarde de ceva. Într-adevăr, înainte de C99 trebuia să utilizați tipuri specifice furnizorului dacă doriți un număr întreg pe 64 de biți.

Numerele cu virgulă mobilă sunt de obicei utilizate ca o aproximare a numerelor reale. Singura precizie este suficientă de bună parte din timp, dar nu este greu să găsești probleme în cazul în care provoacă o cantitate inacceptabilă de eroare de rotunjire. Mă aștept că cererea din calculul științific este ceea ce a determinat suportul în virgulă dublă de precizie să fie omniprezent cu mult înainte de 64 de biți sprijinul întreg a fost.

Ceea ce mi se pare curios este că C pare să încurajeze utilizarea dublei, în timp ce fortranul pare să încurajeze utilizarea unei precizii simple.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *