Dokładność typów double i decimal

0

Pytanie pewnie jedno z prostszych, otóż napisałem prosty program konsolowy do wyliczania jakie nominały ekspedientka powinna wydać w zależności od reszty. Wszystko na ifach, nominały poszeregowane od największego nominału do najmniejszego (500 zł do 1 grosz) po wydaniu zmienna double money zmniejszała się odpowiednio. Problem jest w chwili gdy program powinien wydać jeden grosz a zmienna money jest w tym momencie mniejsza od niego (nie wiem dlaczego). Chodzi tu o błędy w zapisie liczb w komputerze? Zawsze mi się wydawało, że takie błędy występują przy dosyć małych liczbach a nie 0,01. Użyłem również zmiennej decimal, która okazała się jeszcze mniej dokładna niż double. Wytłumaczy ktoś o co chodzi?

1

Pokaż kod.

0
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Program
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Podaj ile reszty kasjerka ma wyplacic \n");
            double money = double.Parse(Console.ReadLine());
            while(money!=0)
            {
                if(money > 500)
                {
                    Console.WriteLine("Wydano 500 zlotych\n");
                    money -= 500;
                    continue;
                }
                if(money > 200)
                {
                    Console.WriteLine("Wydano 200 zlotych\n");
                    money -= 200;
                    continue;
                }
                if(money >100)
                {
                    Console.WriteLine("Wydano 100 zlotych\n");
                    money -= 100;
                    continue;
                }
                if (money > 50)
                {
                    Console.WriteLine("Wydano 50 zlotych\n");
                    money -= 50;
                    continue;
                }
                if (money >20)
                {
                    Console.WriteLine("Wydano 20 zlotych\n");
                    money -= 20;
                    continue;
                }
                if (money > 10)
                {
                    Console.WriteLine("Wydano 10 zlotych\n");
                    money -= 10;
                    continue; 
                }
                if (money > 5)
                {
                    Console.WriteLine("Wydano 5 zlotych\n");
                    money -= 5;
                    continue;
                }
                if (money > 2)
                {
                    Console.WriteLine("Wydano 2 zlote \n");
                    money -= 2;
                    continue;
                }
                if (money >1)
                {
                    Console.WriteLine("Wydano 1 zloty\n");
                    money -= 1;
                    continue;
                }
                if (money > 0.5)
                {
                    Console.WriteLine("Wydano 50 groszy \n");
                    money -= 0.5;
                    continue;
                }
                if (money > 0.2)
                {
                    Console.WriteLine("Wydano 20 groszy \n");
                    money -= 0.2;
                    continue;
                }
                if (money > 0.1)
                {
                    Console.WriteLine("Wydano 10 groszy \n");
                    money -= 0.1;
                    continue;
                }
                if (money > 0.05)
                {
                    Console.WriteLine("Wydano 5 grosze \n");
                    money -= 0.05;
                    continue;
                }
                if (money > 0.02)
                {
                    Console.WriteLine("Wydano 2 grosze \n");
                    money -= 0.02;
                    continue;
                }
                if (money > 0.01)
                {
                    Console.WriteLine("Wydano 1 grosz \n");
                    money -= 0.01;
                    continue;
                }
            }
        }
    }
}
3

Jak ma wydać ostatni grosz, jeżeli if sprawdza czy > niż 1 grosz, a nie >=?

PS: Jeżeli masz dużo powtarzającego kodu, gdzie np. zmienia się tylko jedna rzecz, to zazwyczaj da się go napisać sprytniej ;)

0
WeiXiao napisał(a):

Jak ma wydać ostatni grosz, jeżeli if sprawdza czy > niż 1 grosz, a nie >=?

racja, nie pomyślałem

0

Po kiego grzyba używasz typu double zamiast decimal ?
Tłumaczone było już milion razy że typ double nie nadaje się do obliczeń finansowych .

0
Zimny Krawiec napisał(a):

Po kiego grzyba używasz typu double zamiast decimal ?
Tłumaczone było już milion razy że typ double nie nadaje się do obliczeń finansowych .

Na początku miałem decimal, ale ze względu na to że przy 1groszu nie miałem większy lub równy to wychodziły podobne głupoty co w double

1

Używaj groszy w obliczeniach, a przy wyświetlaniu jedynie dziel przez sto. Używając typu zmiennoprzecinkowego do obliczeń pieniężnych prędzej czy później dostaniesz kopa.

1

Sam program da się skrócić, pozbywając się ifów:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CSharpConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            var nominals = new List<int>
            { 50000, 20000, 10000, 5000, 2000, 1000, 500, 200, 100, 50, 20, 10, 5, 2, 1 };

            int money = 150; // 1,50zł.

            while (money != 0)
            {
                var n = nominals.First(m => money >= m);
                Console.WriteLine(n / 100.0);
                money -= n;
            }
        }
    }
}
0

Linq znam, ale jak widać jeszcze nie mam automatyzmu w korzystaniu z niego. Przykład Grześka bardzo pomocny

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