Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Neuer Zahlentyp - Int128 (https://www.delphipraxis.net/4764-neuer-zahlentyp-int128.html)

Flogo 11. Mai 2003 09:48


Neuer Zahlentyp - Int128
 
Tach Leute
Ich soll für Mathe ein Programm schreiben das die Fibbonacci-Zahlen graphisch darstellt. Das funktioniert soweit auch ganz gut nur ab der 72. Zahl werden die Zahlen so groß, dass selbst Int64 zu groß wird und wieder in den negativen Bereich umschlägt. Mein Lehrer hat mir gesagt ich soll mir einen neuen Zahlentyp deklarieren der auch größere Zahlen speichern kann (Array of Int64 oder so ähnlich) dieser Zahlentyp muss nur addrieren können und eben sehr große Zahlen aufnehmen und anzeigen können. Leider hab ich keine Ahnung wie ich das machen soll (das mit dem addieren). Ich hoffe ihr könnt mir da ein paar denkanstösse geben. :D

tommie-lie 11. Mai 2003 10:39

Wenn der Lehrer das gesagt hat, einfach machen.
Wie addierst du denn schriftlich (also hne Taschenrechner ;-) )? Fängst rechts an und addierst jede Zahl, was größer ist als 10 wird abgeschnitten und zur nächsten Zahl hinzuaddiert. So machen. Dein Array deklarieren, rechts anfangen und die beiden zahlen addieren, den Rest bis 9 nehmen und temporär speichern und für die nächste Zahl verwenden. Wenn du dein Array gleich verkehrt herum anlegst (also die einer-Stellen auf die linke Seite) ist es vielleicht einfacher, "rechts anzufangen" *g*
Die Ausgabe wird zwar ein wenig haarig, weil du jede Zahl einzeln InToStren musst, aber das lässt sich auf diesem Weg nicht anders machen und ließe sich auch durch eine Schleife lösen, die das Teil in einen String schreibt. Genauso kannst du übrigens auch Multiplikation und Subtraktion implementieren, Division wird etwas schwieriger, lässt sich aber auch machen...

jbg 11. Mai 2003 11:05

Zitat:

Zitat von tommie-lie
IntToStren

Das ist gar nicht nötig.
1. Ist es relativ langsam
2. Wenn man schon Werte von 0..9 hat, kann man gleich Ord('0') dazurechnen und hat die Ziffer.

Delphi-Quellcode:
type
  TDezZahl = record
    Negativ: Boolean;
    Stellen: TByteDynArray;
  end;

procedure DezZahlConvertError(const Zahl: string);
begin
  raise EConvertError.CreateFmt('"%s" ist keine gültige Zahl', [Zahl]);
end;

function DezZahlToStr(const Zahl: TDezZahl): string;
var
  i: Integer;
  StartIndex: Integer;
begin
  if Zahl.Negativ then StartIndex := 2 else StartIndex := 1;
  SetLength(Result, Length(Zahl.Stellen) + StartIndex - 1);

  if Zahl.Negativ then
    Result[1] := '-';

  for i := 0 to High(Zahl.Stellen) do
    Result[i + StartIndex] := Char(Ord('0') + Zahl.Stellen[i]);
end;

function StrToDezZahl(const Zahl: string): TDezZahl;
var
  i: Integer;
  StartIndex: Integer;
begin
  if (Length(Zahl) = 0) or (not (Zahl[1] in ['0'..'9', '-', '+'])) then
    DezZahlConvertError(Zahl);

  Result.Negativ := (Zahl[1] = '-');
  if (Result.Negativ) or (Zahl[1] = '+') then
    StartIndex := 2
  else
    StartIndex := 1;

  SetLength(Result.Stellen, Length(Zahl) - (StartIndex - 1));

  for i := StartIndex to Length(Zahl) - 1 do
  begin
    if not (Zahl[i] in ['0'..'9']) then
      DezZahlConvertError(Zahl);

    Result.Stellen[i - StartIndex] := Byte(Ord(Zahl[i]) - Ord('0'));
  end;
end;

tommie-lie 11. Mai 2003 13:32

auch 'ne Möglichkeit *g*

Flogo 11. Mai 2003 14:19

Danke für die schnellen Antworten Ich werds gleich mal versuchen :coder: Ganz so kompliziert muss es gar nich sein weil ich für die fibonaccizahlen weder negative zahlen noch multiplikation,... brauche. trozdem noch eine frage: sollte ich lieber ein array of Int64 nehem und die stellen irgendwie auslesen oder lieber gleich ein array of Byte?

Daniel B 11. Mai 2003 14:26

Hallo,

schau Dir mal das an.
http://www.delphipraxis.net/viewtopic.php?t=1220
Das ganze steht in der Unit JclMath von den Jedi.
Vielleicht solltest Du Dir mal anschauen wie es dort in der Unit gelöst worden ist.

Grüsse, Daniel :hi:

Flogo 11. Mai 2003 16:09

Danke für den tip aber soweit ich das erkennen kann rechnet die function auch nur mit Integer und ist deshalb wahrscheinlich nur bis zur 50.Fibonaccizahl genau. Meine function läuft mit Int64 und kommt auch nur bis zur 92.

tommie-lie 11. Mai 2003 17:21

Hoho, ein array of Int64 wäre vollkommen übertrieben. einfach ein array of Byte. Da jede Zahl nicht größer als 20 wird, hast du da genug Spielraum und einen kleineren Typ gibt es nicht. Jeder Index des arrays entspricht dann einer Stelle. ein array[0..63] of Byte hätte dann 64 Stellen. Du musst halt schauen, wie groß die Zahlen sind. 1000 (eintausend) kriegt man in einem 4-indizierten Array unter, 1000000000 (eine Billion) halt in einem 10-indizierten. Am besten du schreibst dir eine Funktion "Add" (weiß nich, ob's die schon in Delphi irgendwo gibt), die zwei arrays of Byte übernimmt und ein array of Byte wieder ausspuckt. In der addierst du die beiden Zahlen.
An den Stellen, wo du dann in deiner alten Funktion für die Fibonacci-Zahlen folgendes geschrieben hast:
Code:
a := b + c;
schreibst du dann stattdessen:
Code:
a := Add(b, c);
So wäre es am sinnvollsten, sonst musst du den Code zur Addition jedesmal neu eingeben, bzw kopieren.

Flogo 12. Mai 2003 20:38

Vielen Dank für die Tips :hello: und für die Leute die es interresiert mal den kompletten Code
Code:
unit IntXU;

interface

uses Math, Dialogs, SysUtils;

type
  IntX = array of byte;

function add(a, b: IntX): IntX;
function IntXToStr(x: IntX): String;
function IntToIntX(x: Integer): IntX;

implementation

function add(a, b: IntX): IntX;
var i, uebertrag: Integer;
begin
  uebertrag := 0;
  setlength(Result, max(length(a), length(b)));
  for i := 0 to max(length(a), length(b)) - 1 do
  begin
    Result[i] := 0;
    if i < length(a) then Inc(Result[i], a[i]);
    if i < length(b) then Inc(Result[i], b[i]);
    Inc(Result[i], Uebertrag);
    if Result[i] >= 10 then
    begin
      dec(Result[i], 10);
      uebertrag := 1;
    end
    else uebertrag := 0;
  end;
  if uebertrag = 1 then
  begin
    setlength(Result, Length(Result)+1);
    Result[Length(Result)-1] := 1;
  end;
end;

function IntXToStr(x: IntX): String;
var i: Integer;
begin
  SetLength(Result, Length(x));
  for i := 0 to High(x) do
    Result[i+1] := Char(Ord('0') + x[High(x)-i]);
end;

function IntToIntX(x: Integer): IntX;
var i: Integer; Stellen: Byte;
begin
  if x < 0 then exit;
  for i := 1 to 13 do
    if x < power(10, i) then
    begin
      Stellen := i;
      break;
    end;
  setlength(Result, Stellen);
  for i := Stellen - 1 downto 0 do
  begin
    Result[i] := x div round(power(10, i));
    x := x - Result[i] * round(power(10, i));
  end;
end;

end.
PS: Ich weiß es ist nicht perfekt und wahrscheinlich auch nicht besonders gut programmiert (könnte daran liegen dass ich das heute in der mittagspause zusammengezimmert habe und davor noch nie gemacht hab) aber für die Fibonaccizahlen reichts

MatrixStormProgrammierer 30. Mai 2003 18:54

bei:

http://www.delphipraxis.net/internal...ighlight=int64

habe ich schon mal was zur Emulation großer Zahlen geschrieben...

kannst du ja mal lesen, wenn Bock...

cu MatrixStormProgrammierer


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:33 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