problem z kalkulatorem podaje złe wyniki a nawet NaN !?

0

Witam wszystkich :P Chciał bym "przedyskutować" problem odnośnie mojego pseudo kalkulatora. Jestem nowy w programowaniu w javie oraz jestem samoukiem to też na pewno będzie widoczne po moim kodzie ;)

 import java.math.* ;
import javax.swing.* ;


public class Kalorie
{
    public static void main(String[] args)
    {
        String wejscie = JOptionPane.showInputDialog
                ("Ile wazysz ?");
        int y = Integer.parseInt(wejscie);
        
        wejscie = JOptionPane.showInputDialog
                ("ile masz wzrostu ?");
        int x = Integer.parseInt(wejscie);
        
        wejscie = JOptionPane.showInputDialog
                ("ile czasu biegasz ? *czas w minutach +/-*");
        int z = Integer.parseInt(wejscie);
        
        wejscie = JOptionPane.showInputDialog
                ("jaki dystans przebiegniesz ?");
        int k = Integer.parseInt(wejscie);
        
        wejscie = JOptionPane.showInputDialog
                ("jak duzo jjesz posilkow przed bieganiem ? *1/2 dania*");
        int u = Integer.parseInt(wejscie);
        
        int kalorie; 
        int bmi; 
        int sk; 
        final int u1 = 50;
        final int l =100;
            
            double bmi1 = y/(x * x);
            double sk1 = k/z;
            double kalor = bmi1 * u1 * l;
                    
                    if (kalor>0);
                        double motyw = kalor / sk1;
                        System.out.println
                        (motyw);
            
                    if (bmi1>0);
                        System.out.println
                        (bmi1);
                        
                    if (sk1>0);
                        System.out.println
                        (sk1); 
                    
           
           System.exit(0);
    }
}

Coś tu straszliwie nie gra z tego względu iż eclipse cały czas mi podświetla moje zadeklarowane "zmienne ", gdzie kompletnie się już zgubiłem no i niestety zmieszałem :D
Wydaje mi się przynajmniej że potrzeba to "zapętlić" tylko nie bardzo kminie jak to zrobić poprawnie.

Wszystkie negatywne komentarze mile widziane ;P

Edit: Po otagowaniu w ramach komentarzu pierwszych trzech zmiennych oraz ostatniego wejścia, program liczy tylko nie podoba mi się jego liczenie.
Wyniki: NaN
0.0
0.0
Nie mam pojeęcia czemu...

0

!. Co znaczy słowo "jjesz"?
2. Dzielenie liczb typu int w Javie daje wynik typu int: 3/5 = 0, a ty zapewne oczekujesz 0.6.

double sk1 = ((double)k)/z;
0
bogdans napisał(a):

!. Co znaczy słowo "jjesz"?



Nie sugeruj się tymi literówkami pisałem to tak żeby coś było :P i w miarę1żebym wiedział o co chodzi.

co do tego double okej zmieniło mi to lekko wyniki z tym że dalej nie liczy poprawnie np : bmi np podaje wagę 90 wzrost 184 czyli bmi powinno wychodzić 376,17(7) załóżmy, co też jest błędem bo skala bmi wedle wikipedii wynosi maksymalną wartość 40. Tu też chciałbym poprawić sposób obliczania tego ażeby był on poprawny, z tym że kompletnie nie mam na to pomysłu jak ograniczyć wyliczanie do 40...
0

Nie rozumiem dlaczego przy 90 kg wagi i 184 cm wzrostu ma wychodzić bmi 376,17... ? z tego co wiem to wzór na bmi jest taki: waga [kg] / wzrost^2 [m], więc w podanym przez Ciebie przykładzie powinno wyjść jakieś 26,583.... Co do Twoich wyników to bmi obliczasz tak: double bmi1 = y/(x * x); ale y i x to int więc itak powinny Ci wychodzić liczby całkowite. Aby było poprawnie najpierw zadbaj o to aby waga była w kilogramach - double, a wzrost w metrach - double. Później wykonuj obliczenia.

Przypuszczam, że liczysz kwadrat wzrostu w centymetrach, więc wychodzi on większy niż licznik tego ułamka (waga), a ponieważ masz wszystko na intach to wychodzą Ci zera. Na konieć rzutujesz otrzymane 0 na double i w rezultacie zostajesz z 0.0 :)

0

Przekminiłem to w ten sposób:

import javax.swing.* ;


public class Kalorie
{
    public static void main(String[] args)
    { 
        double cm = 0.032808399;
        double kg = 2.20462262;

        String wejscie = JOptionPane.showInputDialog
                ("Ile wazysz ?");
        int y = Integer.parseInt(wejscie);
        
        wejscie = JOptionPane.showInputDialog
                ("ile masz wzrostu ?");
        double x = Integer.parseInt(wejscie);

            double y1 = y * cm;
            double x1 = x * kg;
            double bmi1 = y1/(x1 * x1);

                        if (bmi1>0);
                        System.out.println
                        (bmi1);

  System.exit(0);
    }
}

dane do konwersjii (cm, kg) znalazłem na myprograming[...], zasadniczo nie bardzo wiem skąd gość który zrobił konwenter wynalazł te liczby ktoś mnie może ukierunkować ?

Co do wyniku to nadal wychodzi mało interesujący ( jest z kosmosu ;) ) :

1.7944170340364447E-5

Jeszcze coś się pojawiło co irytuje moje oczy mianowicie komunikat:

Line breakpoint:Kalorie [line: 40] - main(String[])

w/w komunikat podpowiada żeby dać funkcję break jak dobrze to rozkminiam, jeśli tak to w jakim celu ?

0

Wychodzą ci wyniki z kosmosu, bo bmi liczy się waga w kilogramach podzielone przez kwadrat wzrostu w METRACH

w/w komunikat podpowiada żeby dać funkcję break jak dobrze to rozkminiam, jeśli tak to w jakim celu ?

Nie, breakpoint to jest 'pauza' w programie, która ułatwi ci debugowanie - ogółem, na pewno ktoś inny ci to lepiej wytłumaczy.

0

Dżizas, te dane do konwersji to nie wiem jak mają działać. Napisz sobie własną metodę weryfikującą dane i ew. konwertującą jednostki, jeżeli zajdzie taka potrzeba. Zamiast przepisywać skądś kod, którego nie rozumiesz, może najpierw sam pomyśl. Jak ktoś Ci poda wagę np 80, to nie zastanawia Cię po co to mnożyć przez jakieś 2,204.... ? To samo się tyczy wzrostu. Będziesz miał wyniki z kosmosu, jeżeli Twój kod jest z kosmosu i sam go nie rozumiesz.

0

Magiczne zmienne, od czego są ?

double cm = 0.032808399;
double kg = 2.20462262;

Z Wiki o BMI tego nie widzę:
http://pl.wikipedia.org/wiki/Body_Mass_Index

BMI = masa(kg)/Wzrost^2 (m)
czyli np: BMI = 80/1.8^2 = 80/3,24 = 24,69

Podawanie wzrostu możesz w cm, ale póżniej musisz podzielic przez 100 by przejsc na jednostke metrów i musisz pamiętac ze jednostka metrów to ma być double!!

np.

double m = wzrost/100 

Te przeliczenia wyrzuć:

double y1 = y * cm;
double x1 = x * kg;

i zamiast :

x1 * x1

użyj

Math.pow(x1,2);
0

Poszedłem nawet kawałek dalej wyniki się zgadzają teraz mój kod wygląda następująco:

 
package bmicalc;

import javax.swing.JOptionPane;

public class Calc {
    public static void main(String[] args) {
            
String wejscie = JOptionPane.showInputDialog
    ("Ile wazysz (kg)?");
int kg = Integer.parseInt(wejscie);

wejscie = JOptionPane.showInputDialog
    ("ile masz wzrostu (cm)?");
double cm = Integer.parseInt(wejscie);

double m1 = cm / 100;
double bmi1 = kg / Math.pow(m1,2);


                    if (bmi1 > 0);{
                    System.out.println
                    (bmi1);
                    }
                    if (bmi1 < 18);{
                    JOptionPane.showMessageDialog
                    (null, "masz niedowage", "nazwa",JOptionPane.INFORMATION_MESSAGE);
                    }                    
                    if (bmi1 > 18);{
                    JOptionPane.showMessageDialog
                    (null, "masz dobrą wage", "nazwa", JOptionPane.INFORMATION_MESSAGE);
                    }
                    if  (bmi1 < 24);{
                    JOptionPane.showMessageDialog
                    (null, "masz dobrą wage", "nazwa", JOptionPane.INFORMATION_MESSAGE);
                    }
                    if (bmi1 > 25);{
                    JOptionPane.showMessageDialog
                    (null, "masz nadwage" , "nazwa",JOptionPane.INFORMATION_MESSAGE );
                    }
                    
                    System.exit(0);
                
    }
}

Z tym że utknąłem na kolejnym etapie gdzie jak widać chodzi o komunikaty.
Wyświetlają się wszystkie po kolei kiedy ja chcę tylko dany komunikat do danego wyniku, co do linijek:

if (bmi1 > 18);{
JOptionPane.showMessageDialog
(null, "masz dobrą wage", "nazwa", JOptionPane.INFORMATION_MESSAGE);
}
if (bmi1 < 24);{
JOptionPane.showMessageDialog
(null, "masz dobrą wage", "nazwa", JOptionPane.INFORMATION_MESSAGE);
}

Już wyjaśniam, napisałem to w taki sposób ponieważ nie wiem jak zrobić przedział liczbowy mogę go umieścić w " [] " nawiasach jak w przypadku tablic ?
Czy mam kombinować z break, continue ? nie przekminiam tego zbyt..

1

Operator logiczny && (and)

if(bmi > 18 && bmi < 24)

... swoją drogą nie przypominam sobie żeby w ifach po nawiasach należało stawiać średnik. Jeszcze na przyszłość, podpowiem że operator logiczny OR to ||. Jeszcze pozwolę sobie na taką personalną uwagę, że moim zdaniem lepiej by było żebyś najpierw nauczył się podstaw, a dopiero później siadał do swinga.

1

W tym (i każdym podobnym wierszu)

if (bmi1 > 0);{

usuń średnik.

0

Nie lepiej byłoby tu jeszcze zastosować else if? Po co sprawdzać wszystkie warunki, jeśli pierwszy będzie prawdziwy (a zatem reszta fałszywa) ?

0

Użycie else if to zło. Zaciemnia kod i powoduje, że staje się trudny w czytaniu.

  1. Napisz metodę boolean between(int, int, int), która będzie sprawdzać czy pierwszy argument zawiera się pomiędzy dwoma kolejnymi - poprawisz czytelność kodu.
  2. Rozbij metodę main na kilka mniejszych. Niech jedna przyjmuje dane i zwraca je jako obiekt np:
class Wymiary{
     int cm;
     int kg;
     // reszta kodu
}

Kolejna powinna przyjmować taki obiekt, wyliczać BMI i zwracać wynik.
3. Wynik może być zwykłą liczbą, ale... może być też klasą, która będzie niosła ze sobą pewną logikę:

class Bmi{

    double bmi;

    boolean czyPrawidlowe();{
      return beetwen(bmi, 18, 25);
    }
    // reszta: czyZaNiskie, czyZaWysokie, wartosc itp.
}
  1. Dopisz jakieś testy do tego kodu.
0

Nie potrafie bardzo rozkminic tego. Chcesz bym umiescil dany kod w danej
klasie zeby bylo to bardziej chronologicznie ustawione np.

 
public class Wymiary {
        //podaje wymiary
}
class Przelicz {
       //przelicza wartosci np. cm na metry tylko niby nie potrzeba tego tu dawac a w klasie wyrzej by wystarczylo
}
class Bmi{
        // liczy juz bmi zapisuje wynik korzystajac z klas/ powyrzej
}
class Wyniki{
        //te klase tez mozna by przypisac juz do bmi bo nie wyglada mi to zbyt owocujaco tutaj
}
class Sprawdz{
        //sprawdza wyniki czy jest to dobrze obliczone jesli wartosc = true uzywa funkcji podaj jezeli nie to wraca do     
        //liczenia dopiero podaje jezeli jest wartosc true ?
}
class Podaj{
        //podaje juz sprawdzony wynik co mozna by tez przypisac do klasy sprawdz.
}

tylko ze wtedy klasa ponizej bedzie musiala pobierac informacje z
poprzedniej i tak w kolo macieju az do wyniku o ile to dobrze
interpretuje.

1

Myślisz na poziomie nawet nie strukturalnym, a jakimś prestrukturalnym.
Po pierwsze klasy współpracują ze sobą, ale kolejność ich deklaracji w kodzie nie jest istotna.
Po drugie zaproponowałem rozwiązanie w którym dzielimy klasy na dwie grupy - dane i logikę. Do grupy danych należą Wymiary i BMI do logiki Przelicz, Sprawdź.
Po trzecie zastanów się jakimi bytami operujesz i jakie operacje przeprowadzasz.

  • Wprowadzasz wymiary -> istnieje klasa pozwalająca na wprowadzenie danych w taki sposób, że w wyniku jej działania dostajesz obiekt klasy Wymiary
  • Wyliczasz BMI na podstawie wymiarów -> Istnieje klasa Wylicz, która pobiera dane w postaci obiektu klasy Wymiary i na ich podstawie wyznacza BMI.
  • Sprawdź BMI -> istnieje klasa, która sprawdza wyliczone BMI i na podstawie takiego testu wypisuje komunikat.
0

Wedle moich mizernych starań zrobiłem coś takiego żeby to w jakkolwiek sposób zrozumieć i chyba jestem w dużym dołku[...]
Wygląda to tak :

package cos;

public class logika {

    int pierwszeDane;
    int drugieDane;
    double przeliczoneDane = drugieDane / 100; 
    logika danych = new logika();
}
class Obliczenia {
    
    private Double pierwsze;
    private int drugie;
    
    public Obliczenia(Double x, int y)
        {
        pierwsze = x;
        drugie = y;
        }
    public Double podajOblicz()
        {
        return pierwsze;
        }
    public double podajObliczd()
        {
        return drugie;
        }
            double Wynik = drugie / Math.pow(pierwsze,1); //blad typu: access and modification
            Wynik = new Object();
    
    }
class sprawdzPodajwynik {
    boolean czyPrawidlowe() {
        Object Wynik;
        Object logika;
        if (Wynik == null)
            return false;
        System.out.println
        ("brak działania " +  Wynik +  logika);
        System.exit(0);
        }
    }

 

Chciałbym, tez uzyc jakos "przeliczoneDane" z tym ze mam juz totalny "burdel" w glowie.
Zmieszalem sie totalnie dlatego wole zapytac co tu jest w dupe :P "jezeli nie wszystko bede zachwycony :P"

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