• 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

VPS Starter Arubacloud
0 głosów
379 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ź 585 wizyt
pytanie zadane 27 sierpnia 2015 w C i C++ przez bli14 Nowicjusz (230 p.)
0 głosów
0 odpowiedzi 2,521 wizyt
0 głosów
1 odpowiedź 160 wizyt
pytanie zadane 17 kwietnia 2015 w C i C++ przez GulderBone Użytkownik (600 p.)

92,454 zapytań

141,262 odpowiedzi

319,089 komentarzy

61,854 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

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 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!

...