Miksi ohjelma laskee väärin jos annat euromääräksi esim. 0.3? Jos taas annat arvoksi 0.1 niin sitten näkyy lajittelevan oikein. Eikö '>=' tarkoita suurempaa tai yhtäsuurta?
Ohjelma kyllä toimii jos muutan arvot tyyliin: 0.1 -> 0.09, 0.2 -> 0.19 jne.
# -*- coding: latin-1 -*- # Python 3.1.1 euromäärä = float(input('Anna euromäärä: ')) e2 = 0 e1 = 0 cnt50 = 0 cnt20 = 0 cnt10 = 0 cnt5 = 0 while True: if euromäärä >= 2: e2 += 1 euromäärä -= 2 elif euromäärä >= 1: e1 += 1 euromäärä -= 1 elif euromäärä >= 0.5: cnt50 += 1 euromäärä -= 0.5 elif euromäärä >= 0.2: cnt20 += 1 euromäärä -= 0.2 elif euromäärä >= 0.1: cnt10 += 1 euromäärä -= 0.1 elif euromäärä >= 0.05: cnt5 += 1 euromäärä -= 0.05 else: break print (e2, 'kpl 2 e') print (e1, 'kpl 1 e') print (cnt50, 'kpl 50 cnt') print (cnt20, 'kpl 20 cnt') print (cnt10, 'kpl 10 cnt') print (cnt5, 'kpl 5 cnt') print ('Verottaja vei', euromäärä)
Liukuluvuissa (float) on niiden luonteesta johtuvia pyöristysvirheitä, joten niitä ei pidä käyttää kun tarvitaan tarkkoja arvoja.
Voit käyttää esim. decimal-moduulia: http://docs.python.org/library/decimal.html
Liukuluvut eivät ole tarkkoja, ja esim. arvoja 0,1 ja 0,2 ei pystytä esittämään tarkasti niillä, joten laskutoimituksista saadaan usein hieman liian pieniä tai liian suuria tuloksia.
Ratkaisuna suosittelen, että käsittelet kaikkia rahamääriä sentteinä ohjelmassasi, ja suoritat muunnoksen euroiksi/euroista aina arvojen lukemisen ja tulostuksen yhteydessä.
Aa, sellaisesta seikasta se siis johtui. Osaanpas nyt varautua jos jatkossa tulee vastaavanlainen tilanne eteen. Yksi vaihtoehto voisi olla kai myös pyöristäminen edellämainittujen lisäksi?
Niin, pyöristäminen on tietysti sinänsä toimiva vaihtoehto niin kauan kuin virheet eivät pääse ryömimään pyöristysrajan yli. Varsinkin virheiden kertautuessa (esim. korkolaskut) se on ihan huomioon otettava skenaario. Itse kyllä suosisin decimal tyyppistä tietotyyppiä rahalaskuissa. Toisaalta tuleehan niilläkin pyöristysvirheitä, jos on esim. 5 desimaalia sisäisesti laskettaessa. Tästä on kuitenkin se hyvä puoli, että voidaan laatia yksiselitteiset pyöristyssäännöt.
Helpoin ja tarkka ratkaisu olisi muuttaa eurot senteiksi heti alkuun. Eli kerrot sadalla (100x) ja käsittelet ongelmaa kokonaisluvuin floatin sijasta (esim. 1€ = 100, 0.01€ = 1 jne).
Aihe on jo aika vanha, joten et voi enää vastata siihen.