mikä on pienin luku suurempi kuin 0? Tämä on yksi niistä yksinkertaisista kysymyksistä, joissa on monimutkaisia vastauksia jossain ”ei ole” ja ”se riippuu”välillä.
jos matemaatikolta kysyy, niin he kertovat, ettei sellaista lukua voi olla, koska se rikkoisi matematiikkaa. Jos on luku n, jossa n on pienin luku 0: n jälkeen, ei voi olla lukua n/2, Koska n on jo pienin. Tämä tarkoittaa, että jako itsessään hajoaa, mistä matemaatikot eivät pidä.
jos kysyt tietokoneelta, saat itse asiassa vastauksen. Toisin kuin reaalimaailmassa, tietokoneissa ei ole ääretöntä määrää numeroita, koska ne eivät yksinkertaisesti mahtuneet. Tietokoneet tallentavat numeroita muistirekistereihin, ja jokaisessa rekisterissä on kiinteä määrä bittejä. Kuvittele, jos sinulla olisi vain kolme numeroa. Suurin luku, jota voisit edustaa, olisi 999. Näin tapahtuu tietokoneella.
tämä tarkoittaa, että tietokoneen kokonaislukujen joukkoa rajoittaa numeroiden lukumäärä. Tietokoneessa luku on ehdottomasti suurin (esimerkiksi INT_MAX
C). Se on luku, jossa on maksimimäärä numeroita, jotka kaikki on asetettu binääriksi 1
. 8-bittisessä järjestelmässä tämä luku olisi 11111111
.
voimme mutkistaa asioita vielä enemmän ottamalla mukaan negatiiviset luvut. Jos meillä on 8 bittiä dataa, Voimme käyttää ensimmäistä bittiä edustamaan numeron merkkiä. 0
plus ja 1
miinus. Nyt numeroissamme on 7 bittiä, joten suurin luku on 011111111
, joka on pienempi kuin edellinen suurin lukumme.
vielä ei ole valmista. Meidän on myös edustettava desimaalilukuja. Vaikka 0,12 on pieni luku, siinä on silti kolme numeroa, aivan kuten 123. Erona on, että on vielä yksi asia, jota meidän täytyy ajatella: desimaalipiste, jota kutsutaan myös radix-pisteeksi. Meidän täytyy tallentaa sekä numeroa, ja asema radix kohta.
vaikka kokonaisluvut ovat rajallisia sen suhteen, kuinka suuria ne voivat olla, desimaaliluvut ovat rajallisia sekä kooltaan että tarkkuudeltaan. Jos sinulla on kiinteä määrä numeroita, on vain niin monta numeroa voit laittaa jälkeen desimaalipilkku. Tämän vuoksi tietokoneiden täytyy pyöristää desimaalilukuja.
miten nämä desimaaliluvut sitten tallennetaan? Tietokoneet ymmärtävät vain kokonaislukuja, joten tarvitsemme tavan tallentaa desimaaliluku vain kokonaislukuja käyttäen.
sano, että meillä on numero 3.14
. Aloitetaan kirjoittamalla kaikki numerot numero. Saamme 314
. Se on alku. Tiedämme, että kertomalla potenssit 10, voimme ”siirtää” desimaalipilkun ympäri numero. 314 * 10^-1
on 31,4, kun taas 314 * 10^-2
on 3,14.
luvulle 3,14 riittää kolme kokonaislukua: 314, 10 ja -2. 314 on mitä kutsutaan significand, ja tämä on kaikki numerot numero kirjoitettu ulos.
10 kutsutaan radiksiksi tai emäkseksi. Tiedämme, että kertomalla kanssa valtuudet 10 voimme siirtää desimaalin piste noin numerot base 10. Sama toimii kaikille lukupohjille: base 2: ssa (tai binäärissä) piste voidaan siirtää kertomalla potensseilla 2.
potenssia, jonka mukaan siirrymme, kutsutaan eksponentiksi, ja se kertoo, missä desimaalipiste on.
jokainen desimaaliluku voidaan kirjoittaa noina kolmena lukuna yksinkertaisella kaavalla:
number = significand * base^exponent3.14 = 314 * 10^-2
32.8 = 328 * 10^-1
tietokone tallentaa desimaaliluku tallentamalla merkki, eksponentti ja significand yhden merkkijonon 32 tai 64 bittiä numeroa. Yleensä on 1 bitti merkki, 11 bittiä tallentaa eksponentti ja 53 bittiä tallentaa significand, lisäämällä jopa 64.
tämä mielessä, palataan kysymykseen: Mikä on pienin ei-nolla-luku? Jos meillä on vain kolme numeroa säästää, pienin mahdollinen luku on 0,01. Neljällä numerolla se on 0,001. Tässä on kuvio: significand on aina sama, vain eksponentti muuttuu.
tarvitaan 1
merkitsevyys, koska se on pienin 0
jälkeen. Sen jälkeen desimaalipilkkua on siirrettävä mahdollisimman pitkälle vasemmalle. Tätä varten tarvitsemme pienimmän (negatiivisimman) mahdollisen eksponentin.
kuinka pieni, riippuu numeron asettelusta muistiin. Jos meillä on 11 bittiä eksponentti, voimme vain kirjoittaa pois numero, joka on 10 bittiä pitkä, jossa 1 bitti varattu merkki. 64-bittisessä järjestelmässä pienin eksponentti on -308
.
lopulta pienin mahdollinen luku 64-bittisessä järjestelmässä olisi noin 1 * 10^-308
. Se on pieni!
totesimme, että on olemassa pienin määrä. Tämä numero kertoo, kuinka paljon voimme luottaa tietokoneeseemme. Jos teet jotain, joka vaatii hyvin suuria tai hyvin tarkkoja lukuja, sinun täytyy pitää tämä numero mielessä.
se, mitä juuri laskimme, on jotain niin sanottua 0: n viimeisen paikan yksikköä eli ulp: tä. Sen lisäksi, että se on todella siisti sana, ulp kertoo meille, mikä on pienin etäisyys kahden numeron välillä tietokoneessa. Laskimme ULP 0, joka on pienin etäisyys 0 ja seuraavan numeron.
jos lasketun arvon lisää arvoon 0 ja yrittää verrata niitä, ne eivät olisi sama luku. Kuitenkin, jos lisäät arvon pienempi kuin ulp, se olisi edelleen sama numero, mitä tietokone on huolissaan.
print(0 == 0 + ulp(0)) // false
print(0 == 0 + ulp(0) / 2) // true
meille on selvää, että kun johonkin lukuun lisätään ei-nolla-arvo, saadaan aikaan eri luku, mutta tietokoneen on pyörähdettävä jossain, joten se ei välttämättä osaa sanoa, ovatko kaksi numeroa samat.
tietokonejärjestelmien vertailun helpottamiseksi käytetään 1: n ulp: tä, ja sitä kutsutaan koneeksi epsilon. Kun tunnet koneen epsilon, voit laskea minkä tahansa muun ulp: n seuraavalla kaavalla:
ulp(x) = machine epsilon * radix^exponent(x)
laskemamme arvo on hyvin pieni,joten et todennäköisesti osu tuohon rajaan koodatessasi. Mutta laskimme arvon 0: lle. Enemmän numeroita tarvitaan vasemmalla puolella desimaalipilkku, vähemmän meillä on oikealla puolella. Tämä tarkoittaa, että mitä suurempi numero, sitä vähemmän tarkkuutta sinulla on. Toisin sanoen ULP on eksponentin suora funktio. Kun desimaalipilkkua siirretään oikealle, ulp kasvaa ja tarkkuus heikkenee.
toivon, että nämä tiedot auttavat sinua seuraavan kerran, kun saat oudon liukulukuvirheen koodiisi. Muista, että tietokoneet ovat aika tehokkaita, mutta tietokoneellakin on rajansa.