AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Unbegrenzt viele Nachkommastellen

Ein Thema von c113plpbr · begonnen am 8. Dez 2003 · letzter Beitrag vom 9. Aug 2011
Antwort Antwort
Seite 6 von 12   « Erste     456 78     Letzte »    
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#51

Re: Unbegrenzt viele Nachkommastellen

  Alt 16. Jan 2004, 14:47
Hi

Mehrere Optimierungsmöglichkeiten fallen mir da ein.

1.) es gibt bessere Typen des verwendeten Chudnovsky Algorithmus, sprich höherdimensionale Formeln. Statt 15 Stellen auf einmal zu berechnen können diese Chudnovsky Formeln z.B. 31 Stellen auf einmal berechnen. Allerdings sind diese Formeln viel komplizierter als die von mir benutzte

2.) die benutzte Formel basiert in weiten Teilen auf dem sogenannten "Binary Splitting". Man kann sich das so vorstellen das das Ziel eine Zahl X mit Y Stellen ist. Nun zerlegt man diese Y Stellen in zwei Teile einen Linken und Rechten Teil. Man versucht nun eine Formel zu finden die den Linken und Rechten Teil separat berechnen kann und dann nur noch den Linken und Rechten Teil miteinander multipliziert. Somit haben wir zwei kleine Berechnungen mit halb so großen Zahlen und deren Resultate werden multipliziert. Man kann nun Rekursiv wiederum den Linken und Rechten Teil teilen, usw. usw. Somit reduziert man die Zahlengrößen in den Berechnungen immer weiter. Wichtig ist es dabei das die beiden Zahlen der Linken und Rechten Seite der Berechnung möglichst gleichgroß sind. Denn dadurch wird der maximale Durchsatz, eg. Geschwindigkeit der Berechnungen erzielt. Es ist nämlich so das man zwei gleichgroße Zahlen am schnellsten Multiplizieren kann, d.h. zB. zwei Zahlen bei denen die eine Zahl 2 mal so lange wie die andere ist, wird immer langsammer pro Bit sein als wenn die beiden Zahlen etwa gleichgroß sind. Nun, exakt hier könnte man ebenfalls ansetzen, denn die von mir benutze Formel zur Pi Berechnung erzeugt NICHT immer gute Rechte + Linke Zahlen. Ziel der Optimierung ist es also die Berechnungen besser auszugleichen.

3.) Der von mir benutzte Binary Splitting Algorithmus ist ein Algo der auf Universalität codiert wurde. Im Falle der Pi Berechnung schleppt dieser Algo. z.B. eine Variable zusätzlich sinnlos mit. Das kostet Zeit. Ziel der Optimierung wäre es also einen eigenen Binary Splitting Algo. zu coden der besser auf die Anforderungen der Pi Formel angepasst ist. Unten habe ich mal den derzeitigen Bin. Splitting Algo. gepostet.

4.) Die Bin. Splitting Callback der Pi Berechnung berechnet viele succzessive Variablen. Im Grunde sind diese voneinander abhängig in ihren Zahlenwerten. Aber! meine Callback berechnet diese Werte immer absolut. Ziel der Optimierung wäre es nun diese Zahlenwerte ebenfalls inkrementell zu erzeugen, sprich die vielen kleinen Multiplikationen durch schnellere inkrementelle Additionen zu ersetzen. Dies ist durchaus möglich, man muß nur die besten Formeln dafür finden.

5.) meine Math. Library nutzt ganz verschiedene Multiplikations-verfahren abhänig von den Zahlengrößen. Für die längst-andauerenen Berechnungen = größten Zahlen wird der asymptotisch schnellste Algorithmus der heutzutage bekannt ist verwendet. Es ist die Modulare Fermat Fast Fourier Transformation von Schönhage und Strassen. Wichtig bei solchen FFT-Multiplikationen ist das Wörtchen "asympthotisch", denn es bedeutet das die Performance-Kurve im Verhältnis zu den Zahlengrößen eben NICHT linear sondern sprunghaft ist. D.h. die FFT berechnet immer in weiten Schranken unterschiedlich große Zahlen mit gleicher Geschwindigkeit. Erst wenn bestimmte Zahlkengrößen überschrittten werden steigt der Zeitaufwand der FFT sprunghaft an. Sozusagen entsteht eine Treppenfunktion in der Performance beim Ansteigen der Zahlengrößen. Nun, Ziel der Optimierung wäre es die Formeln so umzustellen das sie bei der Multiplizierung eben diese Treppenfunktion=asymptotisches Verhalten der FFT berücksichtigt. Kurz gesgt: es ist für die meisten FFT's am besten wenn die Zahlengröße in Bits ein Vielfaches von 2 ist.

6.) An vielen Stellen mit sehr wichtigen math. Funktionen habe ich in Assembler optimiert. Dabei wurden auch die neueren SSE2 Features der CPU's berücksichtigt. Beim SSE2 kann man sagen das dies ein mindestens 2 mal höhere Performance erzeugt. Allerdings es gibt noch genügend Source-Stückchen die noch nicht mit solchem SSE2 Code programmiert sind. Besodners die Funktionen für die FFT hätten das noch Potential. Ziel der Optimierung wäre es also diese wichtigen Sources in SSE2 Assembler zu coden.

7.) ein weiteres Beispiel für eine solche Optimierung ist der verwendete Division Algortihmus. Auch dieser basiert auf dem "Divide and Conquer" Verfahren. Der benutzte Algorithums ist der zur Zeit schnellste bekannte, die "Fast Recursive Karatsuba Division" von Burnikel & Ziegler. Auch dieser Algo. zerlegt das Gesamtproblem der Division in viel immer kleiner werdende Divisionen + Multiplikationen. Die kleinest Einheit von Divisions-Algo. ist aber eine normale Assemblercodierte Division nach Donald E. Knuth. Dieser Code ist aber in i486 Code programmiert. Ziel der Optimierung wäre es diesen Algo. auf SSE2 zu portieren. Dadurch düfte die Division im gesammten ca. 2 mal schneller werden. In einigen Performance-Vergleichen zu anderen Pi-Berechnugs-Programmen zeigte es sich das gerade meine Division um den Faktor 2 bis 3 langsammer ist als die der Konkurrenten. Dies liegt hauptsächlich daran das dieses Programme eine komplett andere Division von großen Zahlen benutzten. Die meisten nutzen eine Reziprokale Division die auf einer Newton Iteration basiert. Normalerweise ist dieser Algo. ineffizienter als der von mir benutzte, mit einer einzigsten Ausnahme. Eben der Divsion von sehr sehr großen Zahlen die die besonderen Eigenschaften besitzen wie sie bei der Pi-Formel von Natur aus entstehen. Somit wäre ein zweite Ziel der Oprimierung diese Reziprokale Division zu codieren.

8.) mein Speichermanagement für die IInteger ist darauf ausgelegt möglichst uuniversell flexibel zu sein. Dies äußerst sich auch darin das im Zahlenbereich bis zu ca. 500.000 Dezimalstellen von Pi mein jetziger Code eben schon ca. 2 mal schneller ist als die anderen Programme. D.h. mein Speichermanagement ist enorm effizient für kleinere Zahlen für kryptographische Algortihmen. Will man aber sehr große Zahlen berechnen, wie eben Pi, so ist es sinnvoller eine komplett andere Strategie im Speichermanagement zu verfolgen. Statt die viele kleinen Speicherzugriffe zu optimieren wird es bei großen Zahlen wichtig den Speicher möglichst linear wiederzuverwenden. Ziel der Optimierung wäre es also alle FFT Operationen innerhalb eines einmalig sehr groß allozierten Speicherbereiches inplaced durchzuführen. Dies bedingt aber eine komplette Neuprogrammierung der internen Zahlendarstellungen und Speicherzugriffe.

9.) der von mir benutzte Binary Splitting Algorithmus enthält eine partielle Formel-Optimierung. D.h. er optimiert bis zu einer Tiefe von 4, bestimmmte Multiplikationen weg. Theoretisch könnte man diese Optimierungstiefe aber viel stärker ausbauen. Dazu müssten alle Zwischenresulate der Callback bekannt sein. Nun könnte man das Bin. Splitting so optimieren das es mit der geringsten Anzahl an nötigen Multiplikationen arbeitet. Allein dies dürfte das Vrfahren mindestens 2 bis 3 mal beschleunigen. Allerdings steigt der Speicherverbrauch enorm an.

Alles in allem würde ich schätzen das alle obigen Optimierungen meine Pi Berechnungen ca. 3 bis 5 mal schneller machen könnten. Damit wäre diese in der Performance ca. 2 mal schneller als das schnellste Pi Programm das es zur Zeit für PC's gibt.
Allerdings, jede der obigen Optimierungen ist wesentlich komplizierter als es die jetzigen Algorithmen eh schon sind. D.h. es ist nicht so einfach wie es sich anhört. Alle bisherigen Algos. sind von mir schon bis zur max. Leistungsgrenze hin optimiert worden.

Gruß Hagen


Hier mal der Binary Spliting Code von mir:


Delphi-Quellcode:
type
  TIIntegerSplitData = packed record
    P,Q,A,B: IInteger;
  end;

  TIIntegerBinarySplittingCallback = procedure(N: Cardinal; var P: TIIntegerSplitData); register;

function NBinarySplitting(var P,Q: IInteger; Count: Integer;
      Callback: TIIntegerBinarySplittingCallback; ImplicitShift: Boolean = True): Cardinal;
type
  TSplitParam = packed record
    P,Q,A,B: IInteger;
    Callback: TIIntegerBinarySplittingCallback;
    CallerEBP: Cardinal;
    CalcP: Boolean;
  end;

  function BinarySplitting(n1,n2: Cardinal; var R: TSplitParam): Cardinal;

    procedure Split_C(n: Cardinal; var R: TSplitParam);
    asm
           PUSH [EDX].TSplitParam.CallerEBP
           CALL [EDX].TSplitParam.CallBack
           POP EAX
    end;

    function Split_1(n: Cardinal; var R: TSplitParam): Cardinal;
    begin
      Split_C(n, R);
      if R.P <> nil then
        if R.A <> nil then NMul(R.A, R.P)
          else R.A := R.P;
      if R.Q <> nil then Result := NShr(R.Q)
        else Result := 0;
    end;

    function Split_2(n: Cardinal; var R: TSplitParam): Cardinal;
    var
      L: TSplitParam;
      rQs,lQs: Cardinal;
    begin
      rQs := 0;
      lQs := 0;
      L.Callback := R.Callback;
      L.CallerEBP := R.CallerEBP;
      L.CalcP := True;

      Split_C(n +0, L);
      Split_C(n +1, R);

    // L.A := (L.A * R.B * R.Q * L.P) shl rQs;
    // R.P = R.P * L.P;
    // R.Q = R.Q * L.Q;
    // R.B = R.B * L.B;
    // R.A = R.A * L.B * R.P + L.A;

      if R.Q <> nil then
      begin
        rQs := NShr(R.Q);
        if L.A <> nil then NMul(L.A, R.Q)
          else NSet(L.A, R.Q);
      end else
        if L.A = nil then NSet(L.A, 1);
      if L.Q <> nil then
      begin
        lQs := NShr(L.Q);
        if R.Q <> nil then NMul(R.Q, L.Q)
          else NSwp(R.Q, L.Q);
      end;
      if L.B <> nil then
        if R.A <> nil then NMul(R.A, L.B)
          else R.A := L.B;
      if R.B <> nil then
      begin
        NMul(L.A, R.B);
        if L.B <> nil then NMul(R.B, L.B);
      end else NSwp(R.B, L.B);
      if L.P <> nil then
      begin
        NMul(L.A, L.P);
        if R.P <> nil then NMul(R.P, L.P)
          else NSwp(R.P, L.P);
      end;
      if R.P <> nil then
        if R.A <> nil then NMul(R.A, R.P)
          else R.A := R.P;
      if rQs > 0 then NShl(L.A, rQs);
      if R.A = nil then
      begin
        NSwp(R.A, L.A);
        NInc(R.A);
      end else NAdd(R.A, L.A);
      Result := rQs + lQs;
    end;

    function Split_3(n: Cardinal; var R: TSplitParam): Cardinal;
    var
      L,M: TSplitParam;
      rQs,lQs,mQs: Cardinal;
    begin
      lQs := 0;
      mQs := 0;
      rQs := 0;
      L.Callback := R.Callback;
      L.CallerEBP := R.CallerEBP;
      M.Callback := R.Callback;
      M.CallerEBP := R.CallerEBP;

      Split_C(n +0, L);
      Split_C(n +1, M);
      Split_C(n +2, R);

      if L.Q <> nil then lQs := NShr(L.Q);
      if M.Q <> nil then mQs := NShr(M.Q);
      if R.Q <> nil then rQs := NShr(R.Q);

    // P := [R.P * [M.P * L.P]]
    // Q := [R.Q * M.Q] * L.Q
    // B := [R.B * M.B] * L.B

    // R.A := ([R.B * M.B] * [R.Q * M.Q] * L.A * L.P) shl (rQs + mQs) +
    // (([M.P * L.P] * R.B * R.Q * M.A) shl rQs) * L.B +
    // [R.P * M.P * L.P] * M.B * R.A

    // R.P := P
    // R.Q := Q
    // R.B := B

      if L.P <> nil then
        if M.P <> nil then NMul(M.P, L.P)
          else M.P := L.P;
      if M.P <> nil then
        if R.P <> nil then NMul(R.P, M.P)
          else R.P := M.P;

      if M.A = nil then NSet(M.A, 1);
      if M.P <> nil then NMul(M.A, M.P);
      if R.B <> nil then NMul(M.A, R.B);
      if R.Q <> nil then NMul(M.A, R.Q);
      if rQs > 0 then NShl(M.A, rQs);

      if R.A = nil then NSet(R.A, 1);
      if R.P <> nil then NMul(R.A, R.P);
      if M.B <> nil then NMul(R.A, M.B);
      NAdd(R.A, M.A);

      if L.B <> nil then NMul(R.A, L.B);
      if M.Q <> nil then
        if R.Q <> nil then NMul(R.Q, M.Q)
          else R.Q := M.Q;
      if M.B <> nil then
        if R.B <> nil then NMul(R.B, M.B)
          else R.B := M.B;

      if L.A = nil then NSet(L.A, 1);
      if L.P <> nil then NMul(L.A, L.P);
      if R.B <> nil then NMul(L.A, R.B);
      if R.Q <> nil then NMul(L.A, R.Q);
      Inc(rQs, mQs);
      if rQs > 0 then NShl(L.A, rQs);
      NAdd(R.A, L.A);

      if L.Q <> nil then
        if R.Q <> nil then NMul(R.Q, L.Q)
          else R.Q := L.Q;

      if L.B <> nil then
        if R.B <> nil then NMul(R.B, L.B)
          else R.B := L.B;

      Result := lQs + rQs;
    end;

    function Split_4(n: Cardinal; var R: TSplitParam): Cardinal;
    var
      L,M,K: TSplitParam;
      rQs,mQs,kQs,lQs: Cardinal;
    begin
      lQs := 0;
      mQs := 0;
      kQs := 0;
      rQs := 0;
      L.Callback := R.Callback;
      L.CallerEBP := R.CallerEBP;
      M.Callback := R.Callback;
      M.CallerEBP := R.CallerEBP;
      K.Callback := R.Callback;
      K.CallerEBP := R.CallerEBP;

      Split_C(n +0, L);
      Split_C(n +1, M);
      Split_C(n +2, K);
      Split_C(n +3, R);

      if L.Q <> nil then lQs := NShr(L.Q);
      if M.Q <> nil then mQs := NShr(M.Q);
      if K.Q <> nil then kQs := NShr(K.Q);
      if R.Q <> nil then rQs := NShr(R.Q);

      if L.P <> nil then
        if M.P <> nil then NMul(M.P, L.P)
          else M.P := L.P;
      if M.P <> nil then
        if K.P <> nil then NMul(K.P, M.P)
          else K.P := M.P;
      if K.P <> nil then
        if R.P <> nil then NMul(R.P, K.P)
          else R.P := K.P;

      if M.A = nil then NSet(M.A, 1);
      if M.P <> nil then NMul(M.A, M.P);
      if L.B <> nil then NMul(M.A, L.B);
      if R.Q <> nil then
        if K.Q <> nil then NMul(K.Q, R.Q)
          else K.Q := R.Q;
      if K.Q <> nil then NMul(M.A, K.Q);
      if M.Q <> nil then NMul(K.Q, M.Q);
      if L.A = nil then NSet(L.A, 1);
      if L.P <> nil then NMul(L.A, L.P);
      if K.Q <> nil then NMul(L.A, K.Q);
      if M.B <> nil then NMul(L.A, M.B);
      if mQs > 0 then NShl(L.A, mQs);
      NAdd(L.A, M.A);
      if R.B <> nil then
        if K.B <> nil then NMul(K.B, R.B)
          else K.B := R.B;
      if K.B <> nil then NMul(L.A, K.B);
      Inc(kQs, rQs);
      if kQs > 0 then NShl(L.A, kQs);
      if K.A = nil then NSet(K.A, 1);
      if K.P <> nil then NMul(K.A, K.P);
      if R.Q <> nil then NMul(K.A, R.Q);
      if R.B <> nil then NMul(K.A, R.B);
      if rQs > 0 then NShl(K.A, rQs);
      if R.A = nil then NSet(R.A, 1);
      if R.P <> nil then NMul(R.A, R.P);
      if K.B <> nil then NMul(R.A, K.B);
      NAdd(R.A, K.A);
      if M.B <> nil then
        if L.B <> nil then NMul(L.B, M.B)
          else L.B := M.B;
      if L.B <> nil then NMul(R.A, L.B);
      NAdd(R.A, L.A);
      NSwp(R.Q, L.Q);
      if K.Q <> nil then
        if R.Q <> nil then NMul(R.Q, K.Q)
          else NSwp(R.Q, K.Q);
      NSwp(R.B, L.B);
      if K.B <> nil then
        if R.B <> nil then NMul(R.B, K.B)
          else NSwp(R.B, K.B);

      Result := lQs + kQs + mQs;
    end;

    function Split_D(n1, n2: Cardinal; var R: TSplitParam): Cardinal;
    var
      L: TSplitParam;
      nM,lQs,rQs: Cardinal;
    begin
      nM := (n1 + n2) shr 1;

      L.Callback := R.Callback;
      L.CallerEBP := R.CallerEBP;
      L.CalcP := True;

      lQs := BinarySplitting(n1, nM, L);
      rQs := BinarySplitting(nM, n2, R);

    // R.A := (R.A * L.B * L.P) + (L.A * R.B * R.Q) shl rQs
    // R.P := R.P * L.P
    // R.Q := R.Q * L.Q
    // R.B := R.B * L.B

      if R.B <> nil then
      begin
        if R.Q <> nil then
        begin
          if L.A <> nil then
          begin
            NMul(L.A, R.B);
            NMul(L.A, R.Q);
            if rQs > 0 then NShl(L.A, rQs);
          end else
          begin
            NMul(L.A, R.B, R.Q);
            if rQs > 0 then NShl(L.A, rQs);
          end;
        end else L.A := R.B;
      end else
        if R.Q <> nil then
          if L.A <> nil then
          begin
            NMul(L.A, R.Q);
            if rQs > 0 then NShl(L.A, rQs);
          end else
            if rQs > 0 then NShl(L.A, R.Q, rQs)
              else L.A := R.Q;

      if L.B <> nil then
      begin
        if R.A <> nil then
        begin
          NMul(R.A, L.B);
          if L.P <> nil then NMul(R.A, L.P);
        end else
          if L.P <> nil then NMul(R.A, L.B, L.P);
      end else
        if L.P <> nil then
          if R.A <> nil then NMul(R.A, L.P)
            else NSet(R.A, L.P);

      if R.A = nil then
      begin
        NSwp(R.A, L.A);
        NInc(R.A);
      end else
        if L.A <> nil then NAdd(R.A, L.A)
          else NInc(R.A);

      if R.CalcP then
        if L.P <> nil then
          if R.P <> nil then NMul(R.P, L.P)
            else NSwp(R.P, L.P);

      if L.Q <> nil then
        if R.Q <> nil then NMul(R.Q, L.Q)
          else NSwp(R.Q, L.B);

      if L.B <> nil then
        if R.B <> nil then NMul(R.B, L.B)
          else NSwp(R.B, L.B);

      Result := lQs + rQs;
    end;

  resourcestring
    sNBinarySplitting = 'NBinarySplitting(), internal error index = 0';
  begin
    case n2 - n1 of
      0: begin
           NRaise(@sNBinarySplitting);
           Result := 0;
         end;
      1: Result := Split_1(n1, R);
      2: Result := Split_2(n1, R);
      3: Result := Split_3(n1, R);
      4: Result := Split_4(n1, R);
    else
      begin
        Result := Split_D(n1, n2, R);
      end;
    end;
  end;

// apply a custom binary splitting computation for linear convergent series
//
// p[0]...p[n] a[n]
// S = P / Q = sum(n=0..Count -1) ----------- ----
// q[0]...q[n] b[n]
//
// TI97-7.ps, Fast multiprecision evaluation of series of rational numbers
// Bruno Haible & Thomas Papanikolaou
// for each coefficient p[n], q[n], a[n], b[n] are callback(N, P, Q, A, B) called.
// The custom callback procedure can access as nested procedure to the owner stack.
// If the IIntegers P,Q,A,B of the callback are unchanged = not assigned = NIL then
// there assumed to a value of +1. That reduce memory, interfaces and speedup.
// Means we can implicate that the callback is called by Callback(n, 1, 1, 1, 1);
resourcestring
  sNBinarySplitting = 'NBinarySplitting(), Count must be >= 0 and Callback <> nil';
var
  D: TSplitParam;
begin
  if (Count < 0) or not Assigned(Callback) then NRaise(@sNBinarySplitting);
  if Count = 0 then
  begin
    NSet(P, 0);
    NSet(Q, 1);
    Result := 0;
  end else
  begin
    asm
         MOV EAX,[EBP]
         MOV D.CallerEBP,EAX
    end;
    D.Callback := Callback;
    D.CalcP := False;
    Result := BinarySplitting(0, Count, D);
    if D.B <> nil then
      if D.Q <> nil then NMul(D.Q, D.B)
        else NSwp(D.Q, D.B);
    if ImplicitShift then
    begin
      NShl(D.Q, Result);
      Result := 0;
    end;
    NSwp(P, D.A);
    NSwp(Q, D.Q);
  end;
end;
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#52

Re: Unbegrenzt viele Nachkommastellen

  Alt 22. Jan 2004, 07:20
@negaH:

Ich hab den Binary-Splitting mal "entmüllt" und auf die NPi-Berechnungen angewandt. Der Fast-Chudnovsky wurde bei 500.000 Nachkommastellen tatsächlich 16 ms schneller.

Du hast doch auch gepostet, es gäbe "Höherdimensionale" Varianten des Chudnovsky-Algos. Was haben wir dabei unter "Höherdimensional" zu verstehen, und vor allem, wie funktioniert er?

BtW: Komm, gib nur die Formeln an, ich will auch mal denken! Und: wie berechnet man die Euler-Zahl e?
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#53

Re: Unbegrenzt viele Nachkommastellen

  Alt 22. Jan 2004, 11:33
Zitat:
Ich hab den Binary-Splitting mal "entmüllt" und auf die NPi-Berechnungen angewandt. Der Fast-Chudnovsky wurde bei 500.000 Nachkommastellen tatsächlich 16 ms schneller.
Jo ich weis, mein derzeitiger Source ist so ziemlich kompliziert und verworren. Ich überlege schon seit damals ob es nicht besser wäre erst mal alle Pi-Callback-Resultate in einem rießig großen Zahlenarray zu speichern. Nun wird mit einem cleveren Softwarealgorithmus die Gemeinsamme Produktbildung innerhalb des Binary Splittings codiert. D.h. dieser neue Binary Splitting Algo. eleminiert als Formaloptimierung ALLE redunadanten Multiplikationen.

Aber du könntest mir mal deine Umsetzung mailen.

Zitat:
Du hast doch auch gepostet, es gäbe "Höherdimensionale" Varianten des Chudnovsky-Algos. Was haben wir dabei unter "Höherdimensional" zu verstehen, und vor allem, wie funktioniert er?
Jay, höherdimensional in zwei Punkten:
1.) man benötigt Rationale Zahlen oder eben Fließkommaarithmetik, dies bringt aber eine gewisse "Unsicherheit" in der Genauigkeit mit sich. D.h. die Dimension in der der Programmiere/Mathematiker seinen Algo. überdenken muß wird höher.
2.) die Formel ansich arbeitet in höherer Dimension, aber dazu solltest du die einschlägigen WEB Seiten/PostScripts studieren. Ich bin einer der Mathematik am liebsten macht wenn ein Problem auch nur mit Halbwissen zu lösen ist. D.h. auch ich verstehe nicht jede Formel zu 100% in all ihren Abgründen, trotzdem kann ich sie programmieren. Nun diese 31 Stellen Chundnovsky Formel ist so ein Monster.

Zitat:
Komm, gib nur die Formeln an, ich will auch mal denken!
Puh, da muß ich erst selber in meinen ganzen PDF/PostScripts suchen. Hier kann ich die Formel auf alle Fälle nicht lesbar posten.

Zitat:
Und: wie berechnet man die Euler-Zahl e?
NExp() ist die Funktion die du suchst.

Delphi-Quellcode:
procedure NExp(var A: IInteger; U,V: Integer);
// A = A * e^(U / V)
Umgeschrieben bedeutet das für dich

A = A * e^(1/1) = A * e^1 = A * e.
Du setzt A z.B. auf A = 10^500000 und rufst danach NExp(A) auf, schon hast du A = e * 10^500000, also die 500000 Dezimalstellen von e.

Gruß Hagen
Angehängte Dateien
Dateityp: ps ti-97-7.ps (452,7 KB, 56x aufgerufen)
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#54

Re: Unbegrenzt viele Nachkommastellen

  Alt 22. Jan 2004, 12:21
Hi negaH!

Das einzige an "entmüllung" ist, alle if-Dinger mir x.B als Bedingung zu löschen.

Ist also nicht wirklich kompliziert
  Mit Zitat antworten Zitat
Benutzerbild von Dano
Dano

Registriert seit: 12. Aug 2004
49 Beiträge
 
#55

Re: Unbegrenzt viele Nachkommastellen

  Alt 28. Aug 2004, 00:04
hi negaH

also dein IInteger fasziniert mich !
hättest du nicht lust eine ordentliche lib zum machen so ähnlich wie gmp aber halt für delphi mit ner kleinen beschreibung aller enthaltenen funktionen ?

weil leider gib es keine vernünftige BigInt lib für delphi
und deine NInts.pas/dcu ist das beste was ich derzeit finden kann

hab zwar auch eine gmp-dll aus der ich die gmp-funktionen importe aber das ist keine saubere lösung

so ein package für delphi wäre echt ne spitzen sache !

mfg
Dano
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#56

Re: Unbegrenzt viele Nachkommastellen

  Alt 28. Aug 2004, 00:43
Danke und ähm

Zitat:
hättest du nicht lust eine ordentliche lib zum machen so ähnlich wie gmp aber halt für delphi mit ner kleinen beschreibung aller enthaltenen funktionen ?
ich dachte immer meine IInteger wären so eine "ordentliche" Lib, für Delphi, mit selbsterklärenden Funktionen (für mich privat ausreichend). Naja muß mich da wohl getäuscht haben, und werde das nächste mal ordentlicher programmieren

Nee, was du möchtest ist eine OpenSource Bibliothek weil es keine freien Sourcen auf diesem Sektor für Delphi gibt. Und tatsächlich meine IInteger sind keine Freeware, da haste Recht. Ich glaube du unterschätzt den Aufwand erheblicheine solche Lib zu coden (ist ja nicht nur die Programmierung). Ich habe ca. 3 Jahre dran gebastelt, ca. 75% ist in Assembler selbst der SSE2 Befehlssatz wird unterstützt. Aber viel wichtiger sind die Algorithmen, und da kann ich sehr stolz behaupten das selbst die GMP Experten Teams nicht so effiziente Algos. enthalten wie in meiner Lib.

Also, bitte warum sollte ich jetzt nun das Bedürfniss haben diese 3 Jahre Spaß mit der Hölle, nochmal zu wiederholen ?

Gruß Hagen
  Mit Zitat antworten Zitat
Benutzerbild von nailor
nailor

Registriert seit: 12. Dez 2002
Ort: Karlsruhe
1.989 Beiträge
 
#57

Re: Unbegrenzt viele Nachkommastellen

  Alt 28. Aug 2004, 01:31
Zitat von negaH:
Also, bitte warum sollte ich jetzt nun das Bedürfniss haben diese 3 Jahre Spaß mit der Hölle, nochmal zu wiederholen?
weil du grade nen 18kb post mit allein 8kb getipptem text gemacht hast und ihr eh schon wieder total am rumphilosophieren seid
Michael N.
http://nailor.devzero.de/code/sharpmath/testing/ --- Tests, Feedback, Anregungen, ... aller Art sehr willkommen!
::: don't try so hard - it'll happen for a reason :::
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#58

Re: Unbegrenzt viele Nachkommastellen

  Alt 28. Aug 2004, 01:41
sorry, wenn dich meine ausführlichen Antworten stören, dann las ichs einfach, tschüß.

Gruß hagen
  Mit Zitat antworten Zitat
Benutzerbild von dizzy
dizzy

Registriert seit: 26. Nov 2003
Ort: Lünen
1.932 Beiträge
 
Delphi 7 Enterprise
 
#59

Re: Unbegrenzt viele Nachkommastellen

  Alt 28. Aug 2004, 01:50
ich glaube nailor hat das eher scherzhaft bzw. "frotzelig" gemeint...
Komm bloß nicht auf die Idee, nicht mehr so grandios zu antworten! Ich verstehe zwar nicht wirklich immer alles, wenn es so ins Detail geht, aber ich lese sowas immer mit sehr großem Interesse! (Gerade was mathematische Klamotten angeht).

Also: Keep cool, and keep on!
Fabian K.
INSERT INTO HandVonFreundin SELECT * FROM Himmel
  Mit Zitat antworten Zitat
Benutzerbild von Nothine
Nothine

Registriert seit: 3. Jul 2004
Ort: Mülheim an der Ruhr
198 Beiträge
 
Delphi 5 Enterprise
 
#60

Re: Unbegrenzt viele Nachkommastellen

  Alt 28. Aug 2004, 02:00
@Hagen ich kann auch nur sagen immer weiter, deine mehr als ausführlichen antworten machen es erst richtig interessant sich hier ein bißchen durchzulesen, vor allem weil mich der mathematische bereich auch sehr interessiert aber man den mit 11. klasse schulbildung noch nich wirklich blickt

also immer weiter so, hör bloß nich auf
if ThisPost is senseless then
ThisPost.WasPostedBy := SomeoneElse();
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 6 von 12   « Erste     456 78     Letzte »    


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 00:57 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