• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Problem z liczbami rzeczywistymi w kalkulatorze

Object Storage Arubacloud
0 głosów
390 wizyt
pytanie zadane 5 listopada 2015 w C# przez Werran Użytkownik (730 p.)

Cześć. Mam problem z kalkulatorem. Wszystko działa poprawnie prócz obliczania liczb rzeczywistych. Mianowicie program zwraca liczbe zmiennoprzecinkową lecz nie moge jej użyć do obliczeń. Przykład dla jasności:

6/4 odda mi normalnie 1,5

2.2 * 2 oddaje mi 0. Przy innych działaniach na zmiennych również występują dziwne liczby.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace kalkulator2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        public char znak;
        public string operacja1;
        public string operacja2;
        public double wynik = 0.0;
        string dot = ".";
        string ciag;
        int liczmy;


        private void Btn0_Click(object sender, EventArgs e)
        {
            BoxWynik.Text += 0.ToString();
            
        }

        private void Btn1_Click(object sender, EventArgs e)
        {
            BoxWynik.Text += 1.ToString();
        }

        private void Btn2_Click(object sender, EventArgs e)
        {
            BoxWynik.Text += 2.ToString();
        }

        private void Btn3_Click(object sender, EventArgs e)
        {
            BoxWynik.Text += 3.ToString();
        }

        private void Btn4_Click(object sender, EventArgs e)
        {
            BoxWynik.Text += 4.ToString();
        }

        private void Btn5_Click(object sender, EventArgs e)
        {
            BoxWynik.Text += 5.ToString();
        }

        private void Btn6_Click(object sender, EventArgs e)
        {
            BoxWynik.Text += 6.ToString();
        }

        private void Btn7_Click(object sender, EventArgs e)
        {
            BoxWynik.Text += 7.ToString();
        }

        private void Btn8_Click(object sender, EventArgs e)
        {
            BoxWynik.Text += 8.ToString();
        }

        private void Btn9_Click(object sender, EventArgs e)
        {
            BoxWynik.Text += 9.ToString();
        }


        // Dodaj
        public void BtnPlus_Click(object sender, EventArgs e)
        {
            operacja1 = BoxWynik.Text;
            znak = '+';
            BoxWynik.Text = "";
        }
        //Minus
        private void BtnMinus_Click(object sender, EventArgs e)
        {
            operacja1 = BoxWynik.Text;
            znak = '-';
            BoxWynik.Text = "";
        }
        //Razy
        private void BtnRazy_Click(object sender, EventArgs e)
        {
            operacja1 = BoxWynik.Text;
            znak = '*';
            BoxWynik.Text = "";
        }
        //Dzielenie
        private void BtnDzielenie_Click(object sender, EventArgs e)
        {
            operacja1 = BoxWynik.Text;
            znak = '/';
            BoxWynik.Text = "";
        }

        private void BtnDot_Click(object sender, EventArgs e)
        {
             ciag = BoxWynik.Text;
             liczmy = ciag.IndexOf(dot);
            LblTest.Text = liczmy.ToString();
                if (liczmy == -1)
              {
                  BoxWynik.Text += ".".ToString();
              }
              else
              {
              BoxWynik.Text += "".ToString();
              }
        }

        private void BtnRowna_Click(object sender, EventArgs e)
        {
                operacja2 = BoxWynik.Text;
                double zm1, zm2;
                double.TryParse(operacja1, out zm1);
                double.TryParse(operacja2, out zm2);
                if (znak == '+')
                {
                    wynik = zm1 + zm2;
                    BoxWynik.Text = wynik.ToString();
                }
                else if (znak == '-')
                {
                    wynik = zm1 - zm2;
                    BoxWynik.Text = wynik.ToString();
                }
                else if (znak == '*')
                {
                    wynik = zm1 * zm2;
                    BoxWynik.Text = wynik.ToString();
                }
                else if (znak == '/')
                {
                    if (zm2 == 0)
                    {
                        BoxWynik.Text = "you fool bro".ToString();
                    }
                    else
                    {
                        wynik = zm1 / zm2;
                        BoxWynik.Text = wynik.ToString();
                    }
                }
        }

        private void BtnCzysc_Click(object sender, EventArgs e)
        {
            BoxWynik.Text = "".ToString();
            operacja1 = "".ToString();
            operacja2 = "".ToString();
        }
    }
}

Byłbym wdzięczny za wskazówki odnośnie tego co powinienem dalej czynić by liczby rzeczywiste zaczęły działać poprawnie.

2 odpowiedzi

+3 głosów
odpowiedź 5 listopada 2015 przez furas Maniak (53,800 p.)
wybrane 7 listopada 2015 przez Werran
 
Najlepsza
Sprawdz najpierw czy parsowanie liczby rzeczywistej daje poprawany wynik. Może wpisałeś liczbę z przecinkiem zamiast z kropką ?
komentarz 5 listopada 2015 przez Werran Użytkownik (730 p.)
Trafiłeś w sedno. Parsowanie działa dobrze z liczbami całkowitymi, natomiast przy liczbach rzeczywistych zamienia liczbe w 0. Masz jakiś pomysł co mógłbym w tym przypadku zrobić?
komentarz 5 listopada 2015 przez furas Maniak (53,800 p.)
To teraz cofaj się w kodzie. Jeśli nie parsuje to sprawdź jakie dane dostaje TryParse - może otrzymuje inne niż Tobie się wydaje, że powinien dostać ;)

Przy okazji dowiesz się dla jakich tekstów zwraca `zero`.
komentarz 5 listopada 2015 przez furas Maniak (53,800 p.)
Może się okazać, że przy parsowaniu bierze pod uwagę ustawienia narodowościowe - domyślnie są chyba ustawienia amerykańskie gdzie używa się przecinka zamiast kropki dla oddzielenia części całkowitej od pozostałej części.
komentarz 5 listopada 2015 przez drek Gaduła (4,980 p.)

A może użyj takiej funkcji? Wtedy możesz sobie wstawiać kropki lub przecinki. Osobiście w swoim programie bym tylko pozwolił albo tylko na kropki albo tylko przecinki - nigdy bym nie mieszał. Jak widzisz niżej ja poszedłem na łatwiznę i w przypadku gdy znajdują się jakieś przecinki to zamieniam je na kropki i tyle.

private static bool Parsuj(string str, out double wynik) {
            return double.TryParse(str.Replace(',', '.'), NumberStyles.Any, NumberFormatInfo.InvariantInfo, out wynik);
}

Sposób użycia:

double d1, d2;
var res1 = Parsuj("1,5", out d1);
var res2 = Parsuj("1.5", out d2);

komentarz 7 listopada 2015 przez Werran Użytkownik (730 p.)
Dałbym Ci najlepszą odpowiedź za to, ponieważ użyłem Twojej magicznej funkcji z małą modyfikacją i wszystko pięknie działa. Dzięki wielkie wszystkim, którzy się tu wypowiadali. Nauczyłem sie nowych rzeczy no i rozwiązałem problem.
komentarz 7 listopada 2015 przez furas Maniak (53,800 p.)
@Werran możesz poprosić drek'a aby swój kod wstawił jako odpowiedź i wtedy będziesz mógł dać mu najlepszą odpowiedź :)
komentarz 7 listopada 2015 przez drek Gaduła (4,980 p.)
@furas Nie zależy mi aby była ona oznaczona jako najlepsza :) Najważniejsze, że Warran rozwiązał swój problem i co ważniejsze nauczył się czegoś nowego :)
+1 głos
odpowiedź 5 listopada 2015 przez drek Gaduła (4,980 p.)

Uważam, że pytanie jest zbyt szerokie... Nawet nie dałeś całego kodu aby u siebie ten kod skompilować... Rozumiem, że jesteś początkujący, więc ok. Używanie debuggera to najszybszy i najwygodniejszy sposób na znalezienie problemów w kodzie. Jeśli używasz visual studio, to jest wbudowany w IDE bardzo dobry debugger. Nawet na YT, jeśli nie lubisz czytać, znalazłem jakieś video pokazujące jak używać debuggera: https://www.youtube.com/watch?v=C0vDKXIq_9A

Jeśli z jakiegoś powodu nie chcesz / nie możesz używać debuggera to poprostu tymczasowo użyj jakiegoś prostego logowania w swoim programie np:

var parsowanie1UdaloSie = double.TryParse(operacja1, out zm1)

File.AppendAllText ("c:\\dupa.txt", "parsowanie1 " +operacja1 + ". sukces?: " + parsowanie1UdaloSie + ". sparsowana wartosc: " + zm1 + "\r\n");

var parsowanie2UdaloSie double.TryParse(operacja2, out zm2)

File.AppendAllText ("c:\\dupa.txt", "parsowanie2 " +operacja2 + ". sukces?: " + parsowanie2UdaloSie + ". sparsowana wartosc: " + zm2 + "\r\n");

Później uruchamiasz program, wprowadzasz dane i zamykasz program. Później patrzysz co się zapisało w logu i patrzysz czy wejścia i wyjścia funkcji są takie jak oczekiwałeś. Byś w trzy sekundy widział, czy w parsowaniu tkwi problem czy w czymś innym. Tak czy inaczej wydaje się, że w parsowaniu coś nie działa (być może format). Powodzenia w debuggingu :)

 

komentarz 7 listopada 2015 przez Werran Użytkownik (730 p.)
Udało mi się zdebugować! Dzięki wielkie za naprowadzenie czym jest w ogóle debug programu. Okazało się, że musze wstawiać przecinek zamiast kropki. Niby takie proste a postrafi narobić zamieszania.

Podobne pytania

+1 głos
1 odpowiedź 590 wizyt
pytanie zadane 27 sierpnia 2015 w C i C++ przez bli14 Nowicjusz (230 p.)
0 głosów
0 odpowiedzi 2,537 wizyt
0 głosów
1 odpowiedź 167 wizyt
pytanie zadane 17 kwietnia 2015 w C i C++ przez GulderBone Użytkownik (600 p.)

92,536 zapytań

141,377 odpowiedzi

319,456 komentarzy

61,922 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...