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 2 von 2     12   
Benutzerbild von himitsu
himitsu

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

Re: Wie aus Daten ganze prozentuale Ergebnisse berechnen

  Alt 15. Feb 2009, 12:24
Und das obwohl's noch nichtmal fertig war/ist

Och, sooooo inperformant isses nun auch nicht.
Meistens wird der meiste ja eh nicht ausgeführt und nach maxinam nur einer Runde wird's oftmals auch schon fertig sein.

Die Funktion Math.SumInt hab ich jetzt absichtlich nicht verwendet, da die erste Sum-Schleife schon für die Parameter-Kontrolle verwendet wurde und due 2 kleine Schleife die Bereichsprüfungen der Math.SumInt nicht benötigt.

Es können auch nur negative oder nur positive Werte übergeben werden.

Na gut, ich denk ein paar Optimierungen wären noch möglich, aber erstmal gucken, ob es auch richtig funktioniert.

Delphi-Quellcode:
Uses Types;

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

  Begin
    Maximum := 0;
    For i := 0 to High(Values) do Begin
      If ((Maximum < 0) and (Values[i] > 0))
          or ((Maximum > 0) and (Values[i] < 0)) Then
        Raise Exception.CreateFmt('Invalid Value (%d)', [Values[i]]);
      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
        MinMaxR := -1;
        i2 := -1;
        For i := High(Values) downto 0 do
          If Round(Int(ResultR[i])) = Result[i] Then
            If Abs(Frac(ResultR[i])) > MinMaxR Then Begin
              MinMaxR := Abs(Frac(ResultR[i]));
              i2 := i;
            End;
        If i2 < 0 Then Begin
          MinMaxR := -1;
          i2 := -1;
          For i := High(Values) downto 0 do
            If Abs(Frac(ResultR[i])) > MinMaxR Then Begin
              MinMaxR := Abs(Frac(ResultR[i]));
              i2 := i;
            End;
          If i2 < 0 Then i2 := High(Values);
          Inc(Result[i2]);
        End Else Inc(Result[i2]);
      End Else If i2 > 100 Then Begin
        MinMaxR := -1;
        i2 := -1;
        For i := High(Values) downto 0 do
          If Round(Int(ResultR[i])) <> Result[i] Then
            If Abs(Frac(ResultR[i])) < MinMaxR Then Begin
              MinMaxR := Abs(Frac(ResultR[i]));
              i2 := i;
            End;
        If i2 < 0 Then Begin
          MinMaxR := -1;
          i2 := -1;
          For i := High(Values) downto 0 do
            If Abs(Frac(ResultR[i])) < MinMaxR Then Begin
              MinMaxR := Abs(Frac(ResultR[i]));
              i2 := i;
            End;
          If i2 < 0 Then i2 := High(Values);
          Inc(Result[i2]);
        End Else Inc(Result[i2]);
      End Else Break;
    End;
  End;

Procedure TForm1.FormCreate(Sender: TObject);
  Var R: TIntegerDynArray;
    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;
[add]
@Khabarakh: hop hop, Beeilung .. zwei Funktionen sind besser als eine
$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
 
#12

Re: Wie aus Daten ganze prozentuale Ergebnisse berechnen

  Alt 15. Feb 2009, 13:40
Zitat von himitsu:
Och, sooooo inperformant isses nun auch nicht.
Nicht traurig sein.

Nur optisch gesehen finde ich die Lösung schon heftig (so viele Schleifen und die zig-fach verschachtelt), im Vergleich zu sowas:

Code:
// change the max. array value to get a sum of 100%
else if ($data_sum != 100)
{
   $max_idx = 0;
   $max_val = 0;

   foreach ($data_percentage as $idx => $value)
   {
      if ($value > $max_val)
      {
         $max_val = $value;
         $max_idx = $idx;
      }
   }

   $data_percentage[$max_idx] += (100 - $data_sum);
}
Aber deine Lösung ist auf alle Fälle genauer und wenn man Wert auf Genauigkeit legt, mit Sicherheit die bessere Wahl.

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

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

Re: Wie aus Daten ganze prozentuale Ergebnisse berechnen

  Alt 15. Feb 2009, 13:51
deine etwas "ungerechtere" und schnellere Variante könnte man in Delphi auch recht kurz gestalten
Delphi-Quellcode:
Uses Types, Math;

Function RoundedPercentage(Const Values: Array of Integer): TIntegerDynArray;
  Var i, i2: Integer;

  Begin
    SetLength(Result, Length(Values));
    i2 := SumInt(Values);
    //For i := 0 to High(Values) do Result[i] := Round(Values[i] / i2 * 100);
    For i := 0 to High(Values) do Result[i] := (Values[i] * 100 + i2 shr 1) div i2;
    Inc(Result[High(Result)], 100 - SumInt(Result));
  End;
Code:
15.45  15.45  15.45  15.45  15.45  15.45  7.30

15     15     15     16     16     16     7   // version 1

15     15     15     15     15     15     10  // version 2, also die Jetzige
$2B or not $2B
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


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:20 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