Prozentrechner java

Steev

(ツ)
Registriert
15 Juli 2013
Beiträge
22.194
Ort
zurück ins Dorf
Hi, ich habe diesen Code versucht auszuführen



[src=java]public class PercentageCalculator {

public double calculatePercentage(double obtained, double total) {
return obtained ** 100/total;
}

public static void main(String[]args) {
PercentageCalculator pc = new PercentageCalculator();
Scanner in = new Scanner(System.in);
System.out.println("Enter obtained marks:");
double obtained = in.nextDouble();
System.out.println("Enter total marks:");
double total = in.nextDouble();
System.out.println(
"Percentage obtained: " + pc.calculatePercentage(obtained, total));
}
}[/src]

Das ganze mache ich in Notepad++ mit NppExec mit diesen Befehlen

[src=text]cd $(CURRENT_DIRECTORY)
NPP_SAVE
javac $(FILE_NAME)
java $(NAME_PART)[/src]

Die Datei heißt PercentageCalculator.java

Doch die Console gibt mir diese Fehlermeldung aus

[src=text]CD: C:\Java
Current directory: C:\Java
NPP_SAVE: C:\Java\PercentageCalculator.java
javac PercentageCalculator.java
Process started (PID=7584) >>>
PercentageCalculator.java:4: error: illegal start of expression
return obtained ** 100/total;
^
1 error
<<< Process finished (PID=7584). (Exit code 1)
java PercentageCalculator
Process started (PID=11560) >>>
Fehler: Hauptklasse PercentageCalculator konnte nicht gefunden oder geladen werden
<<< Process finished (PID=11560). (Exit code 1)
================ READY ================[/src]

Kann mir jemand sagen was Notepad da beanstandet, ich werde aus der Fehlermeldung nicht schlau.
 
  • Thread Starter Thread Starter
  • #2
[src=java]import java.util.Scanner;

public class Prozentrechner {

public static void main(String[] args) {

Scanner input=new Scanner(System.in);
double erzieltePunkte=0, gesamtPunkte=0;
float Prozent;

System.out.println("Gib die erzielte Punktzahl ein: ");
erzieltePunkte = input.nextDouble();
System.out.println("Gib die Gesamt-Punktzahl ein: ");
gesamtPunkte = input.nextDouble();

Prozent = (float) ((erzieltePunkte*100)/gesamtPunkte);

System.out.println("Es ist: "+Prozent+"%");
}


}[/src]

Damit klappt es
 
Zuletzt bearbeitet:
Die Fehlermeldung meckert den **-Operator an. Den hab ich in Java noch nie gesehen, und ein einer simplen Prozentberechnung würde ich da auch ein einzelnes * erwarten. Das »Hauptklasse nicht gefunden« wirkt eher wie ein Folgefehler, von dem man sich nicht verwirren lassen darf.
 
  • Thread Starter Thread Starter
  • #4
Daraus jetzt noch eine mini GUI. Kann mir jmd einen Tipp geben? So weit geht mein java-Knowledge noch nicht.
 
  • Thread Starter Thread Starter
  • #5
Daraus jetzt noch eine mini GUI. Kann mir jmd einen Tipp geben? So weit geht mein java-Knowledge noch nicht.

Kommt noch, aber vllt hat jmd einen Tipp für mich, also zweiter Code (!), nicht der aus dem Startpost.

System.out.println("Gib die erzielte Punktzahl ein: ")

System.out.println("Gib die Gesamt-Punktzahl ein: ")

System.out.println("Es ist: "+Prozent+"%")

Das in so Eingabefelder und einem Ausgabefeld :o
 
In Java ist Swing ganz angenehm, um GUIs zu bauen: /
In manchen Entwicklungsumgebungen kannst du dir das Fenster sogar zusammenklicken (bspw in Eclipse oder IntelliJ).
 
Will denn niemand darüber sprechen, dass hier double für eigentlich exakte Rechnungen verwendet werden? :D
 
  • Thread Starter Thread Starter
  • #8
Ja ich denke ich werde float nehmen, weil ich auch mal Punktzahlen mit Kommazahlen habe. Float am Ende, das Ergebnis, auf 2 Stellen hinterm Komma, weiss ich auch noch nicht was ich da machen muss, aber ich lerne java :p
 
double und float sind immer nur ca. Werte und nur geeignet, wenn einem ca. Werte reichen. Für exakte Werte bzw. Fixkomma sollte man lieber einschlägige Klassen verwenden, vermutlich BigDecimal.
 
  • Thread Starter Thread Starter
  • #10
float ist eigentlich ok, mit xxxx Nachkommastellen. Kommt 89,976543 dabei raus, weiss ich ich runde auf 90%. Ist schon ok.Habe da an anderer Stelle (anderes Forum) auch ggf. diese kleine GUI für mich, work in progress.
 
Ich dachte du willst auf zwei Stellen hinter dem Komma runden, wie kann da dann glatt 90 raus kommen? Da würde bei dir 89,98 raus kommen.
 
  • Thread Starter Thread Starter
  • #12
Ja richtig :o aber auch die zwei Stellen hinterm Komma kann ich schnell sehen, also ja die 89,976543 sehe ich 89,98 und schreibe sie auf. Ihr seid ja so Geheimnisvoll. Habe immer den Eindruck, wenn man unter Entwicklern was fragt wird das nicht so ohne weiteres beantwortet. Was ich halt ergooglet habe war dass es da nicht mit einer float Zeile getan ist. Ist aber ok, ich lerne es schon iwie selber. float mit 2 Nachkommastellen ist laut google nicht eindeutig. Dort wieder Forenbeitrag-Ergebnisse wo jeder iwas zu sagt. Was konkretes zum Copy&Paste nicht dabei.
 
Im Gegenteil gibt es eigentlich an jeder Ecke ausschweifende Hilfe, hier doch auch so ziemlich immer.
Solange der float/double Rundungsfehler kleiner oder gleich 0,005 ist bekommst du keine Probleme. Wenn die Rechnung um mehr als 0,005 daneben läge, dann könnte deine Rechnung 89,994 als Ergebnis liefern, was zu 89,99 gerundet werden würde. Von einem korrekten Ergebnis von 90,00 ausgehend. Bei für dich relevante Werte bis 100 kann dir nichts passieren... solange du nur eine einzelne Rechnung machst.
Denn "runden(x) * runden👍" kommt was anderes raus als bei "runden(x*y)". Wenn du jetzt nicht mehr nur x und y hast, sondern 30 Werte und die am Ende rundest, dann addierst sich der Fehler auch auf.
Man sollte eigentlich immer und vor allem als Anfänger BiDecimal verwenden wenn man mit exakten Werten arbeiten will. Alles andere wird dir schlaflose Nächte bereiten.
 
Man sollte eigentlich immer und vor allem als Anfänger BiDecimal verwenden wenn man mit exakten Werten arbeiten will. Alles andere wird dir schlaflose Nächte bereiten.
Sorry, aber das ist doch ziemlich übertrieben. Double hat eine Genauigkeit von ca. 16(!) signifikanten Stellen, float die Hälfte, also 8. Das reicht für die hier gemachten Berechnungen, und eigentlich ziemlich alles was man im Alltag so rechnen mag, vollkommen aus. Natürlich muss man in einigen Fällen vorsichtig sein damit man nicht Genauigkeit verschenkt, aber in dem Fall ist das total irrelevant.
Der bei weitem häufigste Stolperstein für Anfänger sind Vergleiche: man sollte (fast) nie Gleitkomma-Werte mit dem "=="-Operator vergleichen, sondern immer mit einer gewissen Toleranz, also z.B. "if(Math.abs(a-b) < TOLERANZ) { ... }".

Die primitiven Gleitkomma-Typen (float/double) haben den Vorteil dass sie nicht nur um einige Grössenordnungen schneller sind als BigDecimal, sondern in Java auch deutlich lesbareren Code ermöglichen, da Java ja kein Operator Overloading kann. Ich lese deutlich lieber
[src=java]c = 2*x*x + x*y + 4;[/src]
als etwas wie
[src=java]c = x.multiply(x).multiply(new BigDecimal(2.0)).add(x.multiply👍).add(new BigDecimal(4.0));[/src]

Ich will sicher nicht abstreiten dass es sehr gute Gründe geben kann, BigDecimal bzw. allgemein Typen mit garantierter Genauigkeit zu verwenden. Ebenso ist aber kein Zufall, dass heutige CPUs nativ mit Gleitkomma-Zahlen rechnen: sie machen für sehr viele übliche Anwendungen Sinn und sind überhaupt kein Problem, wenn man ihre Grenzen kennt.

tl;dr: in diesem Anwendungsfall ist double die richtige Wahl - float würde ich im Allgemeinen vermeiden, bringt nichts ausser verschenkte Genauigkeit.


Die GUI mit ist aber recht einfach - ein JFrame, JTextField/JFormattedTextField für die Eingabefelder, ein JButton mit ActionListener um die Rechnung zu starten, ein JLabel (oder ein nicht editierbares JTextField) als Ausgabe. Dafür würde ich keinen GUI-Editor bemühen, das kann man sich in 10-20 Zeilen selbst zusammenbauen.
 
Zuletzt bearbeitet:
Sorry, aber das ist doch ziemlich übertrieben. Double hat eine Genauigkeit von ca. 16(!) signifikanten Stellen, float die Hälfte, also 8. Das reicht für die hier gemachten Berechnungen, und eigentlich ziemlich alles was man im Alltag so rechnen mag, vollkommen aus. Natürlich muss man in einigen Fällen vorsichtig sein damit man nicht Genauigkeit verschenkt, aber in dem Fall ist das total irrelevant.
Ich stimme dir auf jeden Fall zu, dass das hier irrelevant ist. Ich würde aber dieses Argument:
Die primitiven Gleitkomma-Typen (float/double) haben den Vorteil dass sie nicht nur um einige Grössenordnungen schneller sind als BigDecimal
Kontern mit: Die Geschwindigkeit reicht für die so ziemlich alles was man im Alltag so rechnen mag vollkommen aus ;).

Der bei weitem häufigste Stolperstein für Anfänger sind Vergleiche: man sollte (fast) nie Gleitkomma-Werte mit dem "=="-Operator vergleichen, sondern immer mit einer gewissen Toleranz, also z.B. "if(Math.abs(a-b) < TOLERANZ) { ... }".
Da würde ich sagen geht das Problem schon weiter, denn die zu wählende Toleranz muss ja abhängig von der Größenordnung der größeren float/double gewählt werden und darf nicht fix sein.

sondern in Java auch deutlich lesbareren Code ermöglichen, da Java ja kein Operator Overloading kann
Ja, das ist definitiv eine ziemlicher Bedauerlichkeit.

Man sollte sich von Anfang an angewöhnen, den passenden Datentyp zu verwenden um nach hinten raus diverse Bugs zu vermeiden. Zumal die Probleme und die Gründe mit float/double ja zum Teil relativ technisch sind und die möglichen Probleme eher zahlreich.
 
Kontern mit: Die Geschwindigkeit reicht für die so ziemlich alles was man im Alltag so rechnen mag vollkommen aus ;).
Fuer so triviale Testprojekte vielleicht. Aber schon wenn's "nur" um ein paar Millionen Werte geht, sieht das recht schnell anders aus. Von klassischen Funktion wie sin/cos/usw., die man dann im Zweifel selbst basteln muesste, mal ganz abgesehen.

Da würde ich sagen geht das Problem schon weiter, denn die zu wählende Toleranz muss ja abhängig von der Größenordnung der größeren float/double gewählt werden und darf nicht fix sein.
Das haengt vom Problem ab. Bei realen Problemen moechte man ja oft eh nicht vergleichen ob zwei Werte exakt gleich sind, sondern, ob sie innerhalb einer gewissen Toleranz liegen. Die Toleranz haengt vom konkreten Problem ab, das auch definiert, in welcher Groessenordnung die Werte liegen werden. Es macht z.B. meist wenig Sinn, ueberall auf eine Nachkommastelle gerundete Werte auszugeben, aber dann intern zu pruefen, ob auch die 5 Stelle hinter dem Komma gleich ist (dann fragt sich der Nutzer, warum er zwei mal "42.0" sieht, die Anwendung aber steif und fest behauptet, die seien nicht gleich).

Wenn man wirklich nur pruefen will, wie viele floats/doubles zwischen zwei Werten liegen, benutzt man Math.ulp().

Man sollte sich von Anfang an angewöhnen, den passenden Datentyp zu verwenden um nach hinten raus diverse Bugs zu vermeiden. Zumal die Probleme und die Gründe mit float/double ja zum Teil relativ technisch sind und die möglichen Probleme eher zahlreich.
Wie gesagt - es gibt sehr viele gute Gruende fuer Gleitkommazahlen. Effizienz, verfuegbare numerische Funktionen und nicht zuletzt die Unterstuetzung in der Sprache der Wahl (hier Java). Ebenso gibt es gute Gruende fuer BigNums mit garantierter Genauigkeit.
Sowohl Gleitkomma- als auch BigNum-Fixkommazahlen haben ihre Tuecken. Bei Gleitkomma-Zahlen ists die nicht garantierte Genauigkeit, aber auch bei BigNum-Fixkommazahlen muss man sich ja zumindest Gedanken machen, wie gross die erwarteten Werte werden und mit welcher Genauigkeit man rechnen moechte, sonst explodiert der Speicher ganz schnell. Das Gleitkommazahlen intrinsisch signifikante Stellen und nicht die Gesamtzahl der Stellen limitieren, ist Fluch und Segen zugleich. Je nach Anwendungsfall :)

Im allgemeinen halte die Wahrscheinlichkeit, sich mit Gleitkommazahlen Probleme einzuhandeln, fuer deutlich geringer, als die Wahrscheinlichkeit, durch unlesbaren Code Bugs zu produzieren (den BigDecimal ja schon fuer triviale Berechnungen produziert, siehe oben).

Was wofuer sinnvoller ist, haengt vom Einzelfall ab. Hier ist double absolut kein Problem, mit BigDecimal macht man sich nur das Leben schwer.
Wenn jemand mit double Kryptografie machen moechte, wuerde ihm aber recht schnell klar, dass das so nicht geht :D

Leute viel wichtiger als das jetzt ist mir eine mini GUI, Applet o.ä.

Um nach so viel Philosophieren doch noch etwas produktives beizutragen ... mal auf die Schnelle als Beispiel zusammengehackt :coffee:
[src=java]
JFrame frame = new JFrame("calc");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(0, 2, 5, 5));
frame.add(new JLabel("Obtained:"));
JFormattedTextField obtainedInput = new JFormattedTextField(new DecimalFormat("0.0"));
obtainedInput.setValue(0.0);
frame.add(obtainedInput);
frame.add(new JLabel("Total:"));
JFormattedTextField totalInput = new JFormattedTextField(new DecimalFormat("0.0"));
totalInput.setValue(0.0);
frame.add(totalInput);
frame.add(Box.createGlue());
JButton calcButton = new JButton("Calculate");
frame.add(calcButton);
frame.add(new JLabel("Result:"));
JFormattedTextField output = new JFormattedTextField(new DecimalFormat("0.00"));
output.setEditable(false);
frame.add(output);

calcButton.addActionListener(e -> output.setValue(calculatePercentage( //
((Number) obtainedInput.getValue()).doubleValue(), //
((Number) totalInput.getValue()).doubleValue()) //
));

frame.pack();
frame.setVisible(true);
[/src]
Koennte man sicher noch schoener machen, vielleicht ein paar Methoden extrahieren, etc.
 
  • Thread Starter Thread Starter
  • #18
Vielen Vielen Danke, aber hm, muss ehrlich zugeben, ich mache das mit Notepad++ und weiss jetzt nicht wie ich das abspeichere und ausführe (.Endung)? Please help :o
 
Das muss irgendwo hin, wo Java es ausfuehrt. Im einfachsten Fall in die main-Methode deiner Klasse.
Ausserdem bin ich davon ausgegangen, dass es schon eine (statische) Methode namens calculatePercentage() gibt, die das Rechnen uebernimmt :)
 
Zurück
Oben