AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Wie aus Daten ganze prozentuale Ergebnisse berechnen
Thema durchsuchen
Ansicht
Themen-Optionen

Wie aus Daten ganze prozentuale Ergebnisse berechnen

Ein Thema von Matze · begonnen am 15. Feb 2009 · letzter Beitrag vom 15. Feb 2009
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Matze
Matze
(Co-Admin)

Registriert seit: 7. Jul 2003
Ort: Schwabenländle
14.929 Beiträge
 
Turbo Delphi für Win32
 
#1

Wie aus Daten ganze prozentuale Ergebnisse berechnen

  Alt 15. Feb 2009, 10:17
Hi,

ich habe Zahlen wie z.B. 124, 63, 235, 95, 12.

Nun möchte ich diese prozentual zusammenfassen, also schauen, welche Zahl wie viel Prozent von der Summe aller Zahlen sind.
Das mache ich bisher so:
  • Alle Zahlen zusammenaddieren (Summe im Beispiel: 529)
  • Einzelne Prozentwerte: (Zahl / Summe) * 100%
Das Ergebnis in dem Fall wäre: 23.4%, 11.9%, 44.4%, 18.0%, 2.3%
Ich möchte nun die gerundeten Werte ohne Nachkommastellen: 23%, 12%, 44%, 18%, 2%

Das macht in der Summe: 23% + 12% + 44% + 18% + 2% = 99%

Ich möchte aber auf 100% kommen.
Natürlich könnte ich sagen, dass ich einfach den letzten Prozentwert nehme und die Differenz der Prozentsumme von 100% (hier: 1%) dazu addiere.
Aber das finde ich keine saubere Lösung. Wenn ein Wert beispielsweise 0% ist und er nachher größer ist, verfälscht das schon stark. Klar könnte ich das auch nur bei einem Wert > 0% hinzu addieren, doch auch das gefällt mir nicht.

Kann man das irgendwie anders lösen, z.B. mit einem anderen Rundungsverfahren?

Grüße, Matze
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#2

Re: Wie aus Daten ganze prozentuale Ergebnisse berechnen

  Alt 15. Feb 2009, 10:38
Alle Werte runden (Round)

und dann könntest du dir noch den Wert mit dem größten und noch nicht aufgerundeten Nachkommaanteil (0.0 > x > 0.5) raussuchten und diesen Nachträglich aufrunden.

Fall aber mehr als 100% rauskam, dann natürlich den kleinesten und noch nicht abgerundeten Wert (0.5 <= x < 1.0) nachträglich abrunden
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von Matze
Matze
(Co-Admin)

Registriert seit: 7. Jul 2003
Ort: Schwabenländle
14.929 Beiträge
 
Turbo Delphi für Win32
 
#3

Re: Wie aus Daten ganze prozentuale Ergebnisse berechnen

  Alt 15. Feb 2009, 10:42
Hi himi,

danke, aber geht das nicht schöner? Das ist ja auch eine Frickel-Lösung, manuell zu prüfen, was auf- und abgerundet wurde und dann entsprechend nachträglich runden.

Grüße, Matze
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#4

Re: Wie aus Daten ganze prozentuale Ergebnisse berechnen

  Alt 15. Feb 2009, 10:57
In nur einer Formal wüßte ich jetzt nicht wie es gehn sollte.

Was noch möglich wäre, erstmal alle Prozentangaben ungerundet ausrechnen
und dann den Wert, ab wann auf-/abgerundet werden soll so verschieben, daß nach'm Runden 100 rauskommt.

Aber ich glaub da ist mein erster Vorschlag effektiver.
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#5

Re: Wie aus Daten ganze prozentuale Ergebnisse berechnen

  Alt 15. Feb 2009, 11:10
Das ganze ist nicht so einfach.

Wenn du z.B. 15,45% sechs mal hast, bleibt noch 7,3% übrig - ergibt 100%

Wenn du jetzt aber rundest: 6*15+7 = 97% - es geht also nicht immer um ein Prozent dass du irgendwo dazutun musst.

Wenn du jetzt diese 3% irgendwo zuschlägst sieht es doof aus. Entweder sind die 6 gleichen Werte nicht mehr gleich oder der letzte Wert wird stark überhöht.

Die Rundungsgrenze zu verschieben hilft auch nicht weiter, da es auf das gleiche hinausläuft - die eigentlich gleichen Werte sind nicht mehr gleich.


Die einzig sinnvolle Lösung in meinen Augen ist das Runden ohne Ausgleich. Dann kommt halt 99% raus, Rundungsfehler eben
Das Beispiel oben ist arg konstruiert, damit so eine große Abweichung herauskommt, im allg. sollte der Fehler um 1% liegen.

P.S.: Bevor du jetzt sagst: "Wann hab ich schon 309/2000 - da bräuchste ich ja 2000 Stimmen" - das ganze geht schon bei 19/123
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#6

Re: Wie aus Daten ganze prozentuale Ergebnisse berechnen

  Alt 15. Feb 2009, 11:18
na Gut, dann halt doch mein erster Vorschlag in einer Schleife,

aber wie jfheins schon sagte, ohne verfälschte Werte ginge das nicht.
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von Matze
Matze
(Co-Admin)

Registriert seit: 7. Jul 2003
Ort: Schwabenländle
14.929 Beiträge
 
Turbo Delphi für Win32
 
#7

Re: Wie aus Daten ganze prozentuale Ergebnisse berechnen

  Alt 15. Feb 2009, 11:24
Ok danke ihr beiden.

Dann mache ich es nun einfach so, dass ich die fehlenden Werte zu 100% dem größten Prozentwert hinzu addiere bzw. davon subtrahiere (falls die Summe > 100% ist), damit ich genau 100% erhalte.
Ich brauche aus Darstellungsgründen exakt 100%. Und ich denke beim höchsten Wert fällt ein verfälschter Wert am wenigsten auf.

Grüße, Matze
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#8

Re: Wie aus Daten ganze prozentuale Ergebnisse berechnen

  Alt 15. Feb 2009, 11:57
Delphi-Quellcode:
Type TIntArray = Array of Integer;

Function RoundedPercentage(Const Values: Array of Integer): TIntArray;
  Var i, i2: Integer;
    Maximum: Int64;
    ResultR: Array of Real;
    MaxR: Real;

  Begin
    Maximum := 0;
    For i := 0 to High(Values) do Begin
      If Values[i] < 0 Then Raise Exception.Create('Fehler');
      Inc(Maximum, Values[i]);
    End;
    SetLength(Result, Length(Values));
    SetLength(ResultR, Length(Values));
    For i := 0 to High(Values) do Begin
      ResultR[i] := Values[i] / Maximum * 100;
      Result[i] := Round(ResultR[i]);
    End;
    While True do Begin
      i2 := 0;
      For i := 0 to High(Values) do Inc(i2, Result[i]);
      If i2 < 100 Then Begin
        MaxR := -1;
        i2 := -1;
        For i := High(Values) downto 0 do
          If Round(Int(ResultR[i])) = Result[i] Then
            If Frac(ResultR[i]) > MaxR Then Begin
              MaxR := Frac(ResultR[i]);
              i2 := i;
            End;
        If i2 < 0 Then Begin

        End Else Inc(Result[i2]);
      End Else If i2 > 100 Then Begin

      End Else Break;
    End;
  End;

Procedure TForm1.FormCreate(Sender: TObject);
  Var R: TIntArray;
    i: Integer;

  Begin
    R := RoundedPercentage([1545, 1545, 1545, 1545, 1545, 1545, 730]);
    Caption := '';
    For i := 0 to High(R) do
      Caption := Caption + ' ' + IntToStr(R[i]);
  End;
hab jetzt noch nicht alle Fälle integriert, aber bei jfheins Beispiel geht es erstmal.
die fehlenden Prozente werden dann "gleichmäßig" von hinten her verteilt

Code:
15.45  15.45  15.45  15.45  15.45  15.45  7.30
15     15     15     16     16     16     7
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von Matze
Matze
(Co-Admin)

Registriert seit: 7. Jul 2003
Ort: Schwabenländle
14.929 Beiträge
 
Turbo Delphi für Win32
 
#9

Re: Wie aus Daten ganze prozentuale Ergebnisse berechnen

  Alt 15. Feb 2009, 12:07
Danke, aber ich habe wohl vergessen zu erwähnen, dass das performant sein muss. *g*
Auf alle Fälle eine interessante Lösung.

Ich denke, mir der simplen Lösung kann ich gut leben. So kritische Daten sind das nicht, dass es da auf einen Prozent hin oder her ankommt.
Aber vielleicht hilft es anderen, dann wäre das u.U. was für die Code-Library.

Grüße, Matze

Edit: Er wurde gerade eben sogar für die Code-Library vorgeschlagen (ich war wieder zu langsam). Dann stufen andere den Source auch als sinnvoll ein.
  Mit Zitat antworten Zitat
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#10

Re: Wie aus Daten ganze prozentuale Ergebnisse berechnen

  Alt 15. Feb 2009, 12:19
Himis erster Vorschlag, der ja doch irgendwie am "Gerechtesten" klingt, lässt sich so vereinheitlichen:
"percent" seien die ungerundeten, "rounded" die gerundeten Prozentzahlen.
"dir" = CompareValue(100, Sum(rounded)) gibt an, ob aufgefüllt (1) oder abgezogen (-1) werden muss.
  • Erstelle aus percents eine neue Liste, indem jedem x "dir * (0.5 - Frac(x))" zugeordnet wird
  • Schmeiße aus ihr alle Einträge < 0 raus (=> falsche Rundungsrichtung)
  • Sortiere sie aufsteigend
  • Nimm davon die ersten "Abs(100 - Sum(rounded))" - das sind die Zahlen, deren gerundete Werte um dir erhöht werden müssen.
Getippt und getestet .

Das einzige Problem ist, dass Delphi für solche mathematischen Spielereien nicht sehr geeignet ist; wer bei meiner Beschreibung an funktionale Funktionen ( ) wie map und filter denkt, denkt genau richtig. Die gibt es in Delphi von Haus aus zwar nicht, aber wenigstens könnte man sie nun - im Gegensatz zu so komischen Sprachen wie Java - mithilfe von Generics, Class Helpers und anonymen Methoden nachbilden. Da dürfte es aber trotzdem schneller sein, meine Beschreibung in ein paar imperative Schleifchen zu übersetzen .

/Edith: Ihr seid einfach zu schnell .

Zitat von Matze:
Danke, aber ich habe wohl vergessen zu erwähnen, dass das performant sein muss. *g*
Wenn man davon ausgeht, dass die Anzahl der auszubessernden Zahlen proportional zur Arraygröße steigt, ist Himis Algo O(n²), meiner O(n log n) (nur das Sortieren fällt ins Gewicht).
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:15 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz