Selittäkää

   1.8 0.1 # => 1.9
   1.8 0.1 == 1.9 # => false
   1.8 0.1 > 1.9 # => true

Miksi se on näin?
7460
Äänestä

Muut lukivat myös

Vastaukset 7

Vanhimmat

Ja kuivaks. Ehkä tämä selittää paremmin...

Tietokone ei siis pysty esittämään desimaalilukua 1.8 tarkasti (eksaktisti) liukulukuna vaan siitä tulee esim. 1.8000001. Ja jos sitten 1.9 samasta syystä on esim. 1.8999999, niin sotkua tulee:

1.8 0.1 onkin siis 1.8000001 0.1000000 ja tulokseksi tulee esim. 1.9000001

1.9000001 ei ole 1.8999999
1.9000001 on suurempi kuin 1.899999

Vedin luvut hatusta eli ne ei välttämättä ole juuri nuo mitä esitin. Mutta periaate on kuitenkin tämä!

Äänestä
  • otetaan pieni heitto huomioon:

    eli inteis vertailu jos samat (eli TRUE)
    if( iLuku1==iLuku2 ) blah;

    ja flotareis
    const float EPSILON 0.0001f; // tai jotain
    if ( fabs(fLuku1 - fLuku2) < EPSILON ) blah;

    Äänestä

  • "Tietokone ei siis pysty esittämään desimaalilukua 1.8 tarkasti (eksaktisti) liukulukuna vaan siitä tulee esim. 1.8000001. "

    Ymmärrän sen kun tietokone käyttää bittejä (32 tai 64) niin lukuja joudutaan pyöristelemään jolloin virheitä tulee. Mutta miksi noin jos luku on vain 1.8?

    Vai pitääkös tietokoneen täyttää nuo loppubitit jolloin joudutaan tekemään 1.8....1 koska desimaali luvuissa ei vika voi olla 0?

    Äänestä

  • Nehr kirjoitti:

    "Tietokone ei siis pysty esittämään desimaalilukua 1.8 tarkasti (eksaktisti) liukulukuna vaan siitä tulee esim. 1.8000001. "

    Ymmärrän sen kun tietokone käyttää bittejä (32 tai 64) niin lukuja joudutaan pyöristelemään jolloin virheitä tulee. Mutta miksi noin jos luku on vain 1.8?

    Vai pitääkös tietokoneen täyttää nuo loppubitit jolloin joudutaan tekemään 1.8....1 koska desimaali luvuissa ei vika voi olla 0?

    http://en.wikipedia.org/wiki/Floating_point

    :: The problem is that floating-point numbers with
    :: a limited number of digits can represent only a
    :: subset of the real numbers, so any real number
    :: outside of that subset (e.g. 1/3, or an
    :: irrational number such as π), cannot be
    :: represented exactly. Even numbers with
    :: extremely short decimal representations can
    :: suffer from this problem. The decimal number
    :: 0.1 is not representable in binary
    :: floating-point of any finite precision. The
    :: exact binary representation would have a "1100"
    :: sequence continuing endlessly:
    ::
    ::
    :: e=-4; s=1100110011001100110011001100110011...,
    :: but when rounded to 24 bits it becomes
    ::
    :: e=-4; s=110011001100110011001101 which is
    :: actually 0.100000001490116119384765625 in
    :: decimal.

    Liukuluvut esitetään jokseenkin näin (binäärinä):

    m * 2^e

    m = mantissa
    e = eksponentti

    Edes lyhyttä desimaalilukua 0.1 on siis mahdoton esittää tarkasti, koska se vaatii loputtomasti toistuvan bittijakson 1100.

    Luvun 0.1 tarkka esitys:

    m = 1100 1100 1100 1100 1100 1100 (loputtomiin asti)
    e = -4

    Luvun 0.1 esitys 24 bitillä:

    m = 1100 1100 1100 1100 1100 1101
    e = -4

    mikä on desimaalilukuna noin 0.100000001490116119384765625.

    Summa summarum:

    Ongelma on se, että kun tietokoneessa reaaliluvut esitetään binäärisinä liukulukuina, niiden tarkkaa esittämistä varten tarvitaan usein loputon määrä bittejä. Mutta koska bittejä ei ole loputtomia määriä vaan niitä on esim. 53 bittiä mantissaa varten, silloin joudutaan tarkka esitys katkaisemaan ja syntyy virhettä.

    Äänestä

Koko ketjusta minulle tuli mieleen:
miksei voisi tehdä systeemiä, jossa laskettaisiin reaaliluvuilla. Hitaampihan se tietysti on, mutta koneet ovat nykyään nopeita.

Äänestä
  • Reaaliluvut eivät ole edes teoriassa minkään äärellisen koneen käsiteltävissä ja koneen on oltava äärellinen, että sitä voisi ajaa. Pidempi selitys menisi erittäin tekniseksi...

    Usein ohjelmoinnin kursseilla puhutaan reaaliluvuista kun tarkoitetaan liukulukuja.

    Äänestä

Kommentoi aloitusta


hurut... kirjoitti:

   1.8 0.1 # => 1.9
   1.8 0.1 == 1.9 # => false
   1.8 0.1 > 1.9 # => true

Miksi se on näin?

Anonyymi
5000

Ilmoita asiaton sisältö

  • Sisältää materiaalia, joka on loukkaavaa, herjaavaa, rasistista, uhkailevaa tai ahdistelevaa.

  • Materiaali sisältää nimiä, yhteystietoja tai muita henkilökohtaisia tietoja. Julkisuuden henkilöistä, julkisissa viroissa toimivista ihmisistä sekä yritysten vastuuhenkilöistä saa keskustella työhön liittyen. Myös yksityiselämään liittyvistä asioista voi keskustella siltä osin, kuin niistä on julkisesti kerrottu.

  • Sisältää lapsille haitallista tai heiltä kiellettyä materiaalia. Seksuaalinen sisältö on sallittua aiheeseen tarkoitetuilla palstoilla, joiden ikäraja on 18 vuotta.

  • Lainvastaista sisältöä voi olla mm. yksityiselämää loukkaavan tiedon levitys, kiihottaminen kansanryhmää vastaan, laiton uhkaaminen, alaikäisiin liittyvä seksuaalinen sisältö/grooming, petokset, identiteettivarkaudet, kunnianloukkaukset ja tekijänoikeusrikkomukset.

  • Sisältö ei liity palstan tai keskusteluketjun aiheeseen.

  • Viesti ei ole suomea tai ruotsia (pl. International Forums), se sisältää mainontaa, se sisältää tekijänoikeuksin suojattua materiaalia, se on massapostitus tai jokin muu syy.

Jaa keskustelu