Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: Desimaaliluvut (Python)

Klvi [09.01.2010 23:02:51]

#

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ä)

Chiman [09.01.2010 23:08:57]

#

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

Sisuaski [09.01.2010 23:14:55]

#

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ä.

Klvi [10.01.2010 00:02:02]

#

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?

Grez [10.01.2010 01:59:59]

#

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.

Jtm [13.01.2010 10:06:25]

#

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).

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta