Prozente werden falsch berechnet

DominikDoom

Mitglied
Hallo Leute,

ich will eine Art Wahlzettel programmieren, bei dem man für verschiedene Parteien abstimmen kann. Jedes Mal, wenn eine Stimme hinzukommt, soll auch der prozentuale Anteil dieser Partei an den Gesamtstimmen aktualisiert werden.
Das Problem ist nun, dass bei der ersten Abstimmung alles funktioniert wie es soll und eine Partei nun 100% hat. Wird allerdings bei einer anderen Partei eine 2. Stimme abgegeben, wird der Prozentwert bei beiden zu 0% anstatt 50%. Die Stimmen für die einzelnen Parteien sowie der Gesamtwert bleiben dabei korrekt erhalten, nur das errechnete Prozentergebnis wird immer zu 0, obwohl es das nicht sollte.
Java:
public void percentUpdate() {
       
        totalCount = spdCount + cduCount + grueneCount + linkeCount + fdpCount;
        cduPercent = (cduCount / totalCount) * 100;
        spdPercent = (spdCount / totalCount) * 100;
        gruenePercent = (grueneCount / totalCount) * 100;
        linkePercent = (linkeCount / totalCount) * 100;
        fdpPercent = (fdpCount / totalCount) * 100;
       
       
        cduBar.setValue(cduPercent);
        spdBar.setValue(spdPercent);
        grueneBar.setValue(gruenePercent);
        linkeBar.setValue(linkePercent);
        fdpBar.setValue(fdpPercent);
    }

cduBar etc. sind Progressbars, mit denen der Prozentanteil angezeigt wird.
Die void percentUpdate() wird beim Drücken eines zur jew. Partei gehörenden Buttons abgerufen:
Java:
private void spdButtonActionPerformed(java.awt.event.ActionEvent evt) {                                         
        spdCount ++;
        spdOutput.setText(spdOutput.getText().valueOf(spdCount));
        percentUpdate();
}                                        

private void cduButtonActionPerformed(java.awt.event.ActionEvent evt) {                                         
        cduCount ++;
        cduOutput.setText(cduOutput.getText().valueOf(cduCount));
        percentUpdate();
}
Nirgends wird einer dieser Prozentwerte absichtlich auf 0 gesetzt, außer bei der Initalisierung, die allerdings definitiv nicht beim drücken der Buttons abgerufen wird.
Ich habe jetzt schon eine ganze Weile herumprobiert, konnte aber keine Lösung finden.
So sieht das Programm aus:
2016-09-09 20_14_18-.png
 
Wenn du mit integer rechnest gibt es keine nachkommastellen.

Rechne doch einmal

(1 / 2) * 100

Das gibt dann 1 / 2 = 0 * 100 = 0

Du musst die Formel umstellen, das du erst mit 100 multiplizierst und dann durch die Anzahl teilst.

Gruß

Claus
 
Oh Mann...
Da hab ich wohl den Wald vor lauter Bäumen nicht gesehen 😉
Noch dem Fehler hätte ich noch Tage gesucht. Jetzt funktioniert alles prima.
 
Nochmal eine Frage:
Momentan berechne ich meine Prozente so:
Java:
percent = count * 100 / totalCount;
percent ist eine Double-Variable.
Ist totalCount z.B 3 und count 2, kommt beim Eintippen in den Taschenrechner 66.66666666666667 raus. In meinem Programm ist das Ergebnis allerdings 66.0 😕
Für die Progressbars brauche ich es sowieso als int, aber ich würde gerne zusätzlich die genauen Prozente mit Labels anzeigen. Momentan sind alle Prozente zusammen immer nur 98 / 99%, was mir zu ungenau ist. Woran könnte es liegen?
 
momentan sind alle Variablen in deiner Rechnung vom Typ int. Dann ist automatisch das Ergebnis auch int.
Du könntest ein "punkt null" bei der 100 hinzufügen, also so:
Java:
percent = count * 100.0 / totalCount;
Dann wird tatsächlich mit double-Genauigkeit gerechnet.
 
Moin, 33.3, 33.3 und 33.3 gibt, in int gerechnet, auch nur 99%. Wer bekommt das zusätzliche 1%? Das ist ein offenes Problem. Wichtig ist aber:
Java:
count * 100 / absCount; // er rechnet mit int und rundet ab

Java:
count * 100.0 / absCount; // er rechnet die kompletten Berechnungen mit double-Genauigkeit und rundet in keine Richtung
 
Hier bitte so könnte es gerechnet werden (aber bin kein Wahlforscher):
Java:
import java.util.*;

/**
* @author DW on 2016/09/09
*/
public class JavaApplication5 {

    private static class Partei implements Comparable<Partei> {

        String bez;
        int alle;
        int anteil;
        double perGenau;
        int perAbgerundet;
        int perIntGenau;

        @Override
        public int compareTo(Partei o) {
            return Double.compare(o.perGenau, this.perGenau);
        }

        @Override
        public String toString() {
            return "Partei{" + "bez=" + bez + ", alle=" + alle + ", anteil=" + anteil + ", perGenau=" + perGenau + ", perAbgerundet=" + perAbgerundet + ", perIntGenau=" + perIntGenau + '}';
        }
    }

    public static void main(String[] args) {
        Partei[] parteien = new Partei[3];
        parteien[0] = new Partei();
        parteien[0].bez = "spd";
        parteien[1] = new Partei();
        parteien[1].bez = "cdu";
        parteien[2] = new Partei();
        parteien[2].bez = "fdp";
        for (int i = 0; i < 6; i++) {
            int j = (int) (Math.random() * 3.0);
            parteien[j].anteil++;
        }
        for (Partei partei : parteien) {
            partei.alle = 6;
            partei.perGenau = (double) partei.anteil / partei.alle * 100.0;
            partei.perAbgerundet = (int) partei.perGenau;
        }
        for (Partei partei : parteien) {
            System.out.println(partei);
        }
        System.out.println("");
        Arrays.sort(parteien);
        for (Partei partei : parteien) {
            System.out.println(partei);
        }
        System.out.println("");
        for (Partei partei : parteien) {
            partei.perIntGenau = partei.perAbgerundet;
        }
        for (Partei partei : parteien) {
            int sum = 0;
            for (Partei p : parteien) {
                sum += p.perIntGenau;
            }
            if (sum < 100) {
                partei.perIntGenau = partei.perIntGenau + 1;
            } else {
                break;
            }
        }
        for (Partei partei : parteien) {
            System.out.println(partei);
        }
        System.out.println("");
    }
}

Code:
Partei{bez=spd, alle=6, anteil=2, perGenau=33.33333333333333, perAbgerundet=33, perIntGenau=0}
Partei{bez=cdu, alle=6, anteil=3, perGenau=50.0, perAbgerundet=50, perIntGenau=0}
Partei{bez=fdp, alle=6, anteil=1, perGenau=16.666666666666664, perAbgerundet=16, perIntGenau=0}

Partei{bez=cdu, alle=6, anteil=3, perGenau=50.0, perAbgerundet=50, perIntGenau=0}
Partei{bez=spd, alle=6, anteil=2, perGenau=33.33333333333333, perAbgerundet=33, perIntGenau=0}
Partei{bez=fdp, alle=6, anteil=1, perGenau=16.666666666666664, perAbgerundet=16, perIntGenau=0}

Partei{bez=cdu, alle=6, anteil=3, perGenau=50.0, perAbgerundet=50, perIntGenau=51}
Partei{bez=spd, alle=6, anteil=2, perGenau=33.33333333333333, perAbgerundet=33, perIntGenau=33}
Partei{bez=fdp, alle=6, anteil=1, perGenau=16.666666666666664, perAbgerundet=16, perIntGenau=16}

Edit richtig wäre so (nimm nur eine kleine Änderung vor):
Code:
Partei{bez=spd, alle=6, anteil=1, perGenau=16.666666666666664, perAbgerundet=16, perIntGenau=16}
Partei{bez=cdu, alle=6, anteil=3, perGenau=50.0, perAbgerundet=50, perIntGenau=50}
Partei{bez=fdp, alle=6, anteil=2, perGenau=33.33333333333333, perAbgerundet=33, perIntGenau=33}

Partei{bez=spd, alle=6, anteil=1, perGenau=16.666666666666664, perAbgerundet=16, perIntGenau=16}
Partei{bez=fdp, alle=6, anteil=2, perGenau=33.33333333333333, perAbgerundet=33, perIntGenau=33}
Partei{bez=cdu, alle=6, anteil=3, perGenau=50.0, perAbgerundet=50, perIntGenau=50}

Partei{bez=spd, alle=6, anteil=1, perGenau=16.666666666666664, perAbgerundet=16, perIntGenau=17}
Partei{bez=fdp, alle=6, anteil=2, perGenau=33.33333333333333, perAbgerundet=33, perIntGenau=33}
Partei{bez=cdu, alle=6, anteil=3, perGenau=50.0, perAbgerundet=50, perIntGenau=50}

SPD bekommt 1% mehr, da Abschneiden. Alle damit in Ordnung?

(Nehme den Nachkommaanteil in den Fokus)
 
Zuletzt bearbeitet von einem Moderator:
Ich finde es schade, dass keiner seinen Senf dazu gibt. Nochmal neu:
Java:
import java.util.*;

/**
 * @author DW on 2016/09/09
 */
public class JavaApplication5 {

    private static class Partei implements Comparable<Partei> {

        String bez;
        int alle;
        int anteil;
        double perGenau;
        int perAbgerundet;
        int perIntGenau;

        @Override
        public int compareTo(Partei o) {
            return Double.compare(o.perGenau - o.perAbgerundet, this.perGenau - this.perAbgerundet);
        }

        @Override
        public String toString() {
            return "Partei{" + "bez=" + bez + ", alle=" + alle + ", anteil=" + anteil + ", perGenau=" + perGenau + ", perAbgerundet=" + perAbgerundet + ", perIntGenau=" + perIntGenau + '}';
        }
    }

    public static void main(String[] args) {
        // init the Parteien
        Partei[] parteien = new Partei[3];
        parteien[0] = new Partei();
        parteien[0].bez = "spd";
        parteien[1] = new Partei();
        parteien[1].bez = "cdu";
        parteien[2] = new Partei();
        parteien[2].bez = "fdp";

        // do the vote
        for (int i = 0; i < 6; i++) {
            int j = (int) (Math.random() * 3.0);
            parteien[j].anteil++;
        }
        for (Partei partei : parteien) {
            partei.alle = 6;
            partei.perGenau = partei.anteil * 100.0 / partei.alle;
            partei.perAbgerundet = (int) partei.perGenau;
            partei.perIntGenau = partei.perAbgerundet;

        }

        // print the vote
        for (Partei partei : parteien) {
            System.out.println(partei);
        }
        System.out.println("");

        // sort the vote
        Arrays.sort(parteien);

        // print the sorted vote
        for (Partei partei : parteien) {
            System.out.println(partei);
        }
        System.out.println("");

        // calc the exactly percents
        for (Partei partei : parteien) {
            int sum = 0;
            for (Partei p : parteien) {
                sum += p.perIntGenau;
            }
            if (sum < 100) {
                partei.perIntGenau = partei.perIntGenau + 1;
            } else {
                break;
            }
        }

        // print finally the votes
        for (Partei partei : parteien) {
            System.out.println(partei);
        }
        System.out.println("");
    }
}

Code:
Partei{bez=spd, alle=6, anteil=1, perGenau=16.666666666666668, perAbgerundet=16, perIntGenau=16}
Partei{bez=cdu, alle=6, anteil=3, perGenau=50.0, perAbgerundet=50, perIntGenau=50}
Partei{bez=fdp, alle=6, anteil=2, perGenau=33.333333333333336, perAbgerundet=33, perIntGenau=33}

Partei{bez=spd, alle=6, anteil=1, perGenau=16.666666666666668, perAbgerundet=16, perIntGenau=16}
Partei{bez=fdp, alle=6, anteil=2, perGenau=33.333333333333336, perAbgerundet=33, perIntGenau=33}
Partei{bez=cdu, alle=6, anteil=3, perGenau=50.0, perAbgerundet=50, perIntGenau=50}

Partei{bez=spd, alle=6, anteil=1, perGenau=16.666666666666668, perAbgerundet=16, perIntGenau=17}
Partei{bez=fdp, alle=6, anteil=2, perGenau=33.333333333333336, perAbgerundet=33, perIntGenau=33}
Partei{bez=cdu, alle=6, anteil=3, perGenau=50.0, perAbgerundet=50, perIntGenau=50}

Also vereinfacht gesagt, die Lösung des problems ist, solange immer aufzurunden, bis die Summe == 100 ist.

Ich verstehe nicht, was daran schwer zu verstehen. Natürlich müsste alles in extra Methoden, und nicht alles in die #main().

Ich hoffe, es konnte etwas behilflich sein. Über ein schnelles "Feedback" würd ich mich freuen.
 

Neue Themen


Zurück
Oben