Problem z przybliżeniem

0

Hej, czy ktoś mógłby mi wytłumaczyć czemu w przypadku takiego kodu

brutto=float(input('Podaj kwote z rachunku: '))
napiwek15=brutto*1.15
napiwek20=brutto*1.2
print('15% napiwek1 to: ',str(napiwek15), '\n20% napiwek2 to: ', str(napiwek20))

przy podaniu brutto:100
dla napiwku15 dostaję 114.9999999?

1

Dobry wynik Dostajesz: 100 * 1.15 czyli 115.

0
lion137 napisał(a):

Dobry wynik Dostajesz: 100 * 1.15 czyli 115.

Dzięki za odpowiedź z tym, że trochę niepokoi mnie to jak wyświetla mi się wynik... dla napiwku1 114.9999999, dla napiwku2 120.0,
Jeśli zamiast 1.15 wpiszę 0.15 to już wtedy jest równe 15.0. Możesz zerknąć na załącznik i ocenić czy się nad tym zastanawiać czy machnąć ręką?

3

Problem polega na tym, że nie masz pojęcia jak funkcjonują liczby zmiennoprzecinkowe (protip: inaczej niż liczą to ludzie na kartce ;-)); rzuć okiem np. tu: https://floating-point-gui.de/

1

A żeby przedstawić odpowiednio liczby zaokrąglij wynik do 2 miejsc po przecinku ale przy samym princie:

print("1% napiwek1 to {:.2f}, \n20% napiwek2 to: {:.2f}".format(napiwek15, napiwek20))

2

I w przyszłości kiedy będziesz chciał aby obliczenia były dokładne, dla liczb zmiennoprzecinkowych, albo używaj ułamków (klasa Fraction), albo bardziej na około, jeśli to możliwe, 'przesuń przecinek/kropkę' w inputcie o pożądaną ilość zer, i dziel dopiero reprezentując wynik.
Ewentualnie jeszcze słyszałem coś o Decimal, ale nie używałem więc nie mogę polecić, osobiście zaprzyjaźniłem się z Fraction i na drugie jeszcze nie znalazłem czasu :)

W obu rozwiązaniach na koniec reprezentując wynik, powinno się dać swobodnie zamienić na float'y tak jak to zaprezentował AsterFV, w drugim sposobie błąd może występować minimalny. Dlatego do dokłądnej reprezentacji cyfr dobrze używać Fractiona, albo nawet rozszerzyć klasę na własny użytek, by odpowiednio dla twoich potrzeb ci wyrzucała wynik:

from fractions import Fraction
class MyFraction(Fraction):
    def __str__(self):
        return #~ Twoj kod formatujący wynik

Inny sposób na zaokrąglanie liczb przy prostych operacjach pokroju twojej, gdzie błędy są nieznaczne:

round(liczba, ilosc_miejsc_po_przecinku)
0
AsterFV napisał(a):

A żeby przedstawić odpowiednio liczby zaokrąglij wynik do 2 miejsc po przecinku ale przy samym princie:

print("1% napiwek1 to {:.2f}, \n20% napiwek2 to: {:.2f}".format(napiwek15, napiwek20))

super, dziękuję :)

1

Problem polega na tym, że ułamki binarne też bywają okresowe, mimo że "dziesiętnie" wyglądają ok. 0.1 binarnie to liczba okresowa, taka jak dziesiętnie 0.3333333..... W efekcie zrobiłeś jakieś obliczenia w stylu 1*1/3 i pytasz czemu wynik to 0.333333333.....4 a nie dokładny wynik.

2

Jeszcze dodam, że jeśli Masz tego typu (i innego) rozkminy, to polecam zamówić tą książkę.

0

@lion137: Jak już reklamujesz książkę, to warto wspomnieć o autorze @Gynvael Coldwind, prawda?
Sam mam i polecam

1 użytkowników online, w tym zalogowanych: 0, gości: 1