AGB  ·  Datenschutz  ·  Impressum  







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

Extended in bruch umformen

Ein Thema von glkgereon · begonnen am 14. Jan 2006 · letzter Beitrag vom 14. Jan 2006
Antwort Antwort
Benutzerbild von glkgereon
glkgereon

Registriert seit: 16. Mär 2004
2.287 Beiträge
 
#1

Extended in bruch umformen

  Alt 14. Jan 2006, 11:39
Hi

Ich kann es ehrlich gesagt kaum glauben, das es zu diesem Thema noch keine wirkliche Lösung gibt...

das einzige was ich finden konnte war folgendes:

Delphi-Quellcode:
procedure DezToBruch(DezimalZahl:double;var Zaehler,Nenner:integer;Tiefe:integer);
const ZuKlein=1E-6;
      Winzig=1E-12;
var GanzAnteil,a,b:integer;
begin
   GanzAnteil:=trunc(DezimalZahl+Winzig);
   if (Tiefe>1) and (abs(DezimalZahl-GanzAnteil)>ZuKlein) then begin
      DezToBruch(1/(DezimalZahl-GanzAnteil),a,b,Tiefe-1);
      Zaehler:=a*GanzAnteil+b;
      Nenner:=a;
   end else begin
      Zaehler:=GanzAnteil;
      Nenner:=1;
   end;
end;
Von hier

Aber wenn man beispielsweise -0.1 reintut, kommt -1/9 raus

gibt es irgendwo eine komplett funktionierende Lösung?
»Unlösbare Probleme sind in der Regel schwierig...«
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

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

Re: Extended in bruch umformen

  Alt 14. Jan 2006, 17:55
Das funktioniert auch nicht, zumindestens nicht ohne eine Library wie mein DECMath

Verdeutliche dir doch mal folgendes

1 * 2^10000, als Extended benötigt man dafür eine 48 Bit große Manitsse die binär 1 einhält und als Exponenten einen maximal 15 Bit großen Wert der 10000 binär enthält. Nun wandele diese Zahl in einen Bruch um ! Es entsteht 1 * 2^10000 / 1 ergo eine Binärzahl aus einer führenden 1 mit 10000 Nullen dran. Diese große Zahl, eg. Bruch kann nur mit einer math. Library die solch großen Zahlen fassen kann dargestellt werden.

Und in fact, in meinem DECMath gibt den Datentyp IRational -> ergo rationale Brüche, die einen Extendend aufnehmen können und diesen dann intern als Bruch darstellen.

Delphi-Quellcode:
var
  R: IRational;
begin
  NSet(R, 1 / 3);
  
  WriteLn('R: ', NStr(R) );
  WriteLn('F: ', NFloat(R) );
  WriteLn('N: ', NStr(R.N) );
  WriteLn('D: ', NStr(R.D) );
end;

// ergibt als Ausgabe

R: 0,333333333333333333333333333333333333333333333333333333
F: 0,3333333

N: 1
D: 3
Intern wird der Extended sehr simpel umgewandelt.

Man extrahiert dazu die Mantisse als 48 Bit Binärzahl und den Exponenten zur Basis 2 ebenfalls als Binärzahl. Je nach Vorzeichen des Exponenten ist die Zahl kleiner 1.0 oder größer.

Delphi-Quellcode:
procedure NSet(var A: IRational; const B: Extended);
type
  ExtRec = packed record
    Man: array[0..1] of Cardinal;
    Exp: Word;
  end;
var
  I: Integer;
begin
  NSet(A, 0);
  if B <> 0 then
    with NAlloc(A)^ do
    begin
      if ExtRec(B).Exp and $7FFF = $7FFF then
      begin // B >= 1.0
        NSet(FN, B);
        NNormalize(A);
      end else
      begin // B < 1.0
        I := (ExtRec(B).Exp and $7FFF) - $3FFE - 64;
        NSet(FN, ExtRec(B).Man, 8);
        NNeg(FN, B < 0);
        if I > 0 then NShl(A, I) else
          if I < 0 then NShr(A, -I)
            else NNormalize(A);
      end;
    end;
end;
Entscheidend ist die sogenannte Normalization eines Bruches, d.h. aus 4/6 den kleinesten eindeutigen Bruch von 2/3 zu finden.

R = N//D
T = GCD(N, D)
R' = (N/T) // (D/T)

// Bruchstrich.

Wie man sieht muß man den größten gemeinsammen Teiler vom Nominator N und Denominator D per GCD() finden. Dieser Wert T wird dann 1 oder größer 1 sein.

Gruß hagen
  Mit Zitat antworten Zitat
Benutzerbild von glkgereon
glkgereon

Registriert seit: 16. Mär 2004
2.287 Beiträge
 
#3

Re: Extended in bruch umformen

  Alt 14. Jan 2006, 19:53
Hmm...irgendwo hatte ich diesen Teil der DEC mal gesehen bei mir auf der Platte....aber ich finde ihn nicht mehr

Gibt es eine neue Version für D2005 oder soll ich den aus dem Thread hier in der DP nehmen?
»Unlösbare Probleme sind in der Regel schwierig...«
  Mit Zitat antworten Zitat
Antwort Antwort


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