Variablen Einheiten umrechen klappt nicht

Lucaaa

Bekanntes Mitglied
Hallo!
Ich möchte Geschwindigkeit (s/t) zeit und weg mittels der jeweils anderen 2 gegebenen größen berechnen. Das klappt auch wunderbar. Nun soll es aber auch die Möglichkeit geben anstatt nur s in meter, t in Sekunden, und v in m/s auch mit Kilometer, stunde, und km/h geben.

Meine Methode spuckt da aber immer anstatt eigentlich 30 (60km, 2h) 0,0008 irgendwas aus.
Bitte um hilfe.
Vielen Dank schonmal.

Java:
package com.ludevstudio.android.physiccalculator;

import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;

import org.w3c.dom.Text;

public class GleichfoermigeBewegung extends android.app.Fragment implements View.OnClickListener {
    //View
    View viewFragment_gleichfoermig;

     //Elemente
    Spinner spinnerWeg;
    Spinner spinnerZeit;
    Spinner spinnerGeschwindigkeit;
    Button btnBerechnen;
    EditText edtWeg, edtZeit, edtGeschwindigkeit;


    //Spinnereinträge
    String[] spinnerWegEintraege = {"m", "km"};
    String[] spinnerZeitEintraege = {"s", "h"};
    String[] spinnerGeschwindigkeitEintraege = {"m/s", "km/h"};

    //Berechnung
    String einheitWeg = "meter";
    String einheitZeit = "sekunde";
    String einheitGeschwindigkeit = "meter/sekunde";
    double s;
    double t;
    double v;


    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        viewFragment_gleichfoermig = (ViewGroup) inflater.inflate(R.layout.fragment_gleichfoermige_bewegung, container, false);
        return viewFragment_gleichfoermig;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

       initKomponenten();
    }

    private void initKomponenten() {
        spinnerWeg = (Spinner) viewFragment_gleichfoermig.findViewById(R.id.spinner_weg_gleichfoermig);
        ArrayAdapter<String> adapterWeg = new ArrayAdapter<String> (getActivity(), android.R.layout.simple_spinner_item, spinnerWegEintraege);
        spinnerWeg.setAdapter(adapterWeg);
        spinnerWeg.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                int positionWeg = spinnerWeg.getSelectedItemPosition();
                if(positionWeg==0) {
                    einheitWeg = "meter";
                }else if(positionWeg==1) {
                    einheitWeg = "kilometer";
                }
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });
            spinnerZeit = (Spinner) viewFragment_gleichfoermig.findViewById(R.id.spinner_zeit_gleichfoermig);
            ArrayAdapter<String> adapterZeit = new ArrayAdapter<String> (getActivity(), android.R.layout.simple_spinner_item, spinnerZeitEintraege);
            spinnerZeit.setAdapter(adapterZeit);
        spinnerZeit.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                int positionZeit = spinnerZeit.getSelectedItemPosition();
                if(positionZeit==0) {
                    einheitZeit = "sekunde";
                }else if(positionZeit==1) {
                    einheitZeit = "stunde";
                }
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });
        spinnerGeschwindigkeit = (Spinner) viewFragment_gleichfoermig.findViewById(R.id.spinner_geschwindigkeit_gleichfoermig);
        ArrayAdapter<String> adapterGeschwindigkeit = new ArrayAdapter<String> (getActivity(), android.R.layout.simple_spinner_item, spinnerGeschwindigkeitEintraege);
        spinnerGeschwindigkeit.setAdapter(adapterGeschwindigkeit);
            edtWeg = (EditText) viewFragment_gleichfoermig.findViewById(R.id.edt_weg_gleichfoermig);
            edtZeit = (EditText) viewFragment_gleichfoermig.findViewById(R.id.edt_zeit_gleichfoermig);
            edtGeschwindigkeit = (EditText) viewFragment_gleichfoermig.findViewById(R.id.edt_geschwindigkeit_gleichfoermig);
        spinnerGeschwindigkeit.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                int positionGeschwindigkeit = spinnerGeschwindigkeit.getSelectedItemPosition();
                if(positionGeschwindigkeit==0) {
                    einheitGeschwindigkeit = "meter/sekunde";
                }else if(positionGeschwindigkeit==1) {
                    einheitWeg = "kilometerprostunde";
                }
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });

        btnBerechnen = (Button) viewFragment_gleichfoermig.findViewById(R.id.button1_berechnen);
            btnBerechnen.setOnClickListener(this);


    }


    @Override
    public void onClick(View view) {
        int id = view.getId();
            s=0; t=0; v=0;
        if(id==R.id.button1_berechnen) {
            try {
                s = Double.parseDouble(edtWeg.getText().toString());
                } catch (Exception e) {
            }
            try {
                t = Double.parseDouble(edtZeit.getText().toString());
            } catch (Exception e) {
            }
            try {
                v = Double.parseDouble(edtGeschwindigkeit.getText().toString());
            } catch (Exception e) {
            }


                   if(!edtWeg.getText().toString().isEmpty() && !edtZeit.getText().toString().isEmpty() && !edtGeschwindigkeit.getText().toString().isEmpty()) {
                       Toast.makeText(getActivity(), getString(R.string.fehlerNichtszuberechnen), Toast.LENGTH_SHORT).show();
                 } else if(!edtWeg.getText().toString().isEmpty() && !edtZeit.getText().toString().isEmpty()) {
                        edtGeschwindigkeit.setText(Double.toString(berechneGeschwindigkeit(s,t)));
                    } else if(!edtZeit.getText().toString().isEmpty() && !edtGeschwindigkeit.getText().toString().isEmpty()) {
                        edtWeg.setText(Double.toString(berechneWeg(v,t)));
            } else if(!edtWeg.getText().toString().isEmpty() && !edtGeschwindigkeit.getText().toString().isEmpty()) {
                  edtZeit.setText(Double.toString(berechneZeit(s,v)));
            } else {
                Toast.makeText(getActivity(), getString(R.string.fehlerNichtgenuegendWerte), Toast.LENGTH_SHORT).show();
                   }



        }

    }

    public double berechneGeschwindigkeit(double s, double t) {
        Double v;

        if(einheitWeg=="kilometer")
            s = s*1000;
        if(einheitZeit=="stunde")
            t = t*3600;
        v = s/t;
        if(einheitGeschwindigkeit=="kilometerprostunde") {
            return (v)*(3.6);
        }

        return v;
    }

    public double berechneWeg(double v, double t) {
        return v*t;
    }
    public double berechneZeit(double s, double v) {
        return s/v;
    }



}
 
Vermutlich nicht. Wenn ihr euch den Code mal genauer anguckt merkt ihr, dass der seine Strings ausschließlich aus dem StringPool bekommt. Somit macht das == vs equals() keinen Unterschied. Ich denke eher er hat sich hier vertan:

Code:
else if(positionGeschwindigkeit==1) {
                    einheitWeg = "kilometerprostunde";
                }

Vermutlich war gemeint:

Code:
else if(positionGeschwindigkeit==1) {
                    einheitGeschwindigkeit =  "kilometerprostunde";
                }

Aber das ist nur eine Vermutung, da ich ebenfalls den Code mehr oder weniger nur überflogen habe...

Vorsicht ist bei solchen String Vergleichen aber trotzdem geboten (Vor allem als Beginner). Falls die Strings mal nicht aus dem String Pool stammen (per Literal erzeugt wie: "ein string") werden solche Vergleiche ( mittels == ) fehlschlagen (wird false ergeben wenn ein true erwartet würde). Darum sollte man sich daran halten Strings mittels equals() zuvergleichen:

Code:
String s1 = "eins";
String s2 = "eins";
booelan istGleich = s1.equals(s2);
 
Wenn ihr euch den Code mal genauer anguckt merkt ihr, dass der seine Strings ausschließlich aus dem StringPool bekommt. Somit macht das == vs equals() keinen Unterschied.

Doch es macht ein Unterschied. Denn mit "kilometer", "stunde" oder "kilometerprostunde" wird ein String erzeugt und bekommt somit eine neue Referenz die es noch nicht gibt.

Java:
// "kilometer" wird neu erzeugt
if(einheitWeg=="kilometer")
    s = s*1000;
// "stunde" wird neu erzeugt   
if(einheitZeit=="stunde")
    t = t*3600;
    v = s/t;
// "kilometerprostunde" wird neu erzeugt   
if(einheitGeschwindigkeit=="kilometerprostunde") {
    return (v)*(3.6);
}
 
Doch es macht ein Unterschied. Denn mit "kilometer", "stunde" oder "kilometerprostunde" wird ein String erzeugt und bekommt somit eine neue Referenz die es noch nicht gibt.

Java:
// "kilometer" wird neu erzeugt
if(einheitWeg=="kilometer")
    s = s*1000;
// "stunde" wird neu erzeugt  
if(einheitZeit=="stunde")
    t = t*3600;
    v = s/t;
// "kilometerprostunde" wird neu erzeugt  
if(einheitGeschwindigkeit=="kilometerprostunde") {
    return (v)*(3.6);
}
Da wird es eben nicht „neu“ erzeugt, sondern kommt aus dem StringPool, so wie alle zu Compile-Zeit bekannten Strings 😉
 
An beide. Es macht hier KEINEN Unterschied weil ALLE Strings hier Literale sind. Es gibt keine Konkatenationen/keine Strings aus Methoden (die evtl ihre String Objekte sonst wie erzeugen) ... nur Literale. Auch wenn an mehreren Stellen "kilometer" einer Variablen zugewiesen wird ist es IMMER dassselbe! Objekt. Weil eben NICHT jedesmal ein neues erzeugt wird, sondern erst der String Pool gecheckt wird, und bei vorhanden sein des gewünschten Strings dieser verwendet wird.

EDIT: etwas zu spät. @mrBrown ich meinte deine beiden Vorredner 🙂
 
An beide. Es macht hier KEINEN Unterschied weil ALLE Strings hier Literale sind. Es gibt keine Konkatenationen/keine Strings aus Methoden (die evtl ihre String Objekte sonst wie erzeugen) ... nur Literale. Auch wenn an mehreren Stellen "kilometer" einer Variablen zugewiesen wird ist es IMMER dassselbe! Objekt. Weil eben NICHT jedesmal ein neues erzeugt wird, sondern erst der String Pool gecheckt wird, und bei vorhanden sein des gewünschten Strings dieser verwendet wird.

EDIT: etwas zu spät. @mrBrown ich meinte deine beiden Vorredner 🙂

Ja sorry, es macht keinen Unterschied.
 
Problem war es kommt nicht das Ergebnis raus, was rauskommen soll. Hab wie gesagt die Logik dahinter nicht überprüft. Mir ist nur aufgefallen, dass er wohl an der einen Stelle den falschen Variablennamen verwendet hat...

Möchte mich auch an dieser Stellen für die CAPS im meinem Post entschuldigen. Sieht ziemlich "besserwisserisch" aus. Sollte mehr der Betonung dienen. Italics wären wohl besser gewesen. Nächstes mal dann. Editieren werde ichs nicht mehr.
 
Problem war es kommt nicht das Ergebnis raus, was rauskommen soll. Hab wie gesagt die Logik dahinter nicht überprüft. Mir ist nur aufgefallen, dass er wohl an der einen Stelle den falschen Variablennamen verwendet hat...

Möchte mich auch an dieser Stellen für die CAPS im meinem Post entschuldigen. Sieht ziemlich "besserwisserisch" aus. Sollte mehr der Betonung dienen. Italics wären wohl besser gewesen. Nächstes mal dann. Editieren werde ichs nicht mehr.

Ist schon ok 😉
 
Habe mal etwas genauer drübergeschaut. Meine Vermutung hat sich wohl bewahrheitet.
Dadurch dass durch den "spinnerGeschwindigkeit" anstelle der Variablen "einheitGeschwindigkeit" die Variable "einheitWeg" beschrieben wurde, kommt es bei der Berechnung zu folgendem Fehler:

Code:
if(einheitWeg=="kilometer")  //einheitsWeg wurde fälschlicherweise überschrieben und somit ist die if-Bedingung nicht erfüllt
            s = s*1000;

if(einheitZeit=="stunde")    //einheitZeit passt noch, also ist die if-Bedingung erfüllt und es wird gerechnet
            t = t*3600;

v = s/t;

if(einheitGeschwindigkeit=="kilometerprostunde") {  //einheitGeschwindigkeit wurde nie auf "kilometerprostunde" gesetzt, if-Bedingung ist nicht erfüllt
            return (v)*(3.6);
        }

Darum ist das Ergebnis bei:
s=60
t=2

2 * 3600 = 7200
60 / 7200 = 0,00833

anstatt:
60 * 1000 = 60000
2 * 3600 = 7200
60000 / 7200 = 8,333
8,333 * 3,6 = 30
 

Zurück
Oben