Autor Beitrag
dagri
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Di 21.12.10 11:41 
ah, danke, hatte ich nicht gesehen. Nur was ist meine Boolean Zahl, also diese HexInput: Boolean? Also was für einen wert muss die am Anfang haben? Kann ich die einfach auf true setzen und dann die funktion aufrufen? Weil dann wär die ja sinnlos :-/
Yogu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Di 21.12.10 13:56 
user profile icondagri hat folgendes geschrieben Zum zitierten Posting springen:
Nur was ist meine Boolean Zahl, also diese HexInput: Boolean?

Die gibt an, ob der Eingabestring Str die Dezimal- oder Hexadezimaldarstellung einer Zahl ist. Wenn du IntToStr verwendest, musst du den Parameter auf False setzen.

Für diesen Beitrag haben gedankt: dagri
dagri
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Fr 07.01.11 16:28 
Kann man auch ein (dynamisches) Array x erstellen, welches die Größe einer BigNumber Zahl b hat, und dann das Array mit x[b] ansprechen? Hat bei mir leider nicht funktioniert und in der Unit habe ich dazu auch nichts gefunden.
Yogu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Fr 07.01.11 16:33 
user profile icondagri hat folgendes geschrieben Zum zitierten Posting springen:
Kann man auch ein (dynamisches) Array x erstellen, welches die Größe einer BigNumber Zahl b hat, und dann das Array mit x[b] ansprechen? Hat bei mir leider nicht funktioniert und in der Unit habe ich dazu auch nichts gefunden.

Ich würde doch fast meinen, ein Array mit 92 23 372 036 854 775 807 Einträgen dürfte genügen, oder? Dann reicht nämlich auch ein 64-Bit-Integer als Typ für den Index.

Für diesen Beitrag haben gedankt: dagri
BenBE Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Sa 08.01.11 08:09 
Dass Delphi Datentypen mit mehr als 2GB zulässt, wäre mir neu. Selbst bei 64 Bit macht das nur wenig Sinn. Und insbesondere array[Int64] of Byte würde als Index-Typ nur bedingt Sinn ergeben ;-)

Außerdem: 256^(2^32) sollten doch wohl für's erste reichen, oder? Ist immerhin 2^35 * ln(2)/ln(10) ... Also ne Zahl mit UNGEFÄHR 20 Milliarden Dezimalstellen...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.

Für diesen Beitrag haben gedankt: dagri
dagri
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Sa 08.01.11 14:56 
user profile iconYogu hat folgendes geschrieben Zum zitierten Posting springen:
user profile icondagri hat folgendes geschrieben Zum zitierten Posting springen:
Kann man auch ein (dynamisches) Array x erstellen, welches die Größe einer BigNumber Zahl b hat, und dann das Array mit x[b] ansprechen? Hat bei mir leider nicht funktioniert und in der Unit habe ich dazu auch nichts gefunden.

Ich würde doch fast meinen, ein Array mit 92 23 372 036 854 775 807 Einträgen dürfte genügen, oder? Dann reicht nämlich auch ein 64-Bit-Integer als Typ für den Index.

Ich habe dies in meinem Programm ausprobiert, allerdings kommt die Fehlermeldung "Fehler bei Bereichsüberprüfung". Das bedeutet doch wohl, dass die Arraygröße bzw. a zu groß ist, oder?:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
var a: Int64;
    x: Array of TBigNumber;
begin
  a := 4294967290;
  setLength(x, a);
end;


Die Fehlermeldung wird bei setLength gezeigt. Leider habe ich vergeblich im Internet nach einer Maximalgröße eines arrays oder nach dem typ der Variable, die die Größe des Arrays definiert, gesucht :(

Moderiert von user profile iconMartok: Delphi-Tags gesetzt
Yogu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Sa 08.01.11 22:18 
user profile iconBenBE hat folgendes geschrieben Zum zitierten Posting springen:
Dass Delphi Datentypen mit mehr als 2GB zulässt, wäre mir neu.

Stimmt, das hatte ich vergessen. Ich wollte nur zeigen, dass ein BigNum vollkommen sinnlos ist.

user profile icondagri hat folgendes geschrieben Zum zitierten Posting springen:
Ich habe dies in meinem Programm ausprobiert, allerdings kommt die Fehlermeldung "Fehler bei Bereichsüberprüfung". Das bedeutet doch wohl, dass die Arraygröße bzw. a zu groß ist, oder?:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
var a: Int64;
    x: Array of TBigNumber;
begin
  a := 4294967290;
  setLength(x, a);
end;

Delphi ist bei mir zwar schon eine Weile her, aber ich glaube, dass dynamische Arrays einen Integer als Index verwenden. Und dessen Maximalwert ist 2 147 483 647. Aber überlege doch mal - ein BigNum braucht im Leerlauf 4 Byte Speicher, also benötigt ein Array mit 2 147 483 647 BigNum-Elementen 8 GB. Und das am Stück. Mit tatsächlichen Zahlen sind es nochmal vieel mehr... Du musst doch einsehen, dass so etwas wahnsinnig übertrieben ist, oder?
Pussyranger
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Di 09.08.11 10:50 
Hallo,
ich möchte auch mit BigNum2 arbeiten, aber ich krieg's noch nicht mal hin zwei Zahlen zu addieren ^^
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TForm1.Button1Click(Sender: TObject);
VAR Zahl1,Zahl2: TBigNumber;
begin
  Zahl1:=-2;
  Zahl2:=0.05;
  Zahl1:=Multiply(Zahl1); //Zahl1 quadrieren
  Zah2:=Add(Zahl1);       //Zahl1+Zahl2
end;

Es scheitert bereits bei der Zuweisung 'Zahl1:=-2;'.

Was mache ich falsch?
LG,

Pussyranger

Moderiert von user profile iconNarses: Quote- durch Delphi-Tags ersetzt
Yogu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Di 09.08.11 13:02 
Hallo user profile iconPussyranger,

eine BigNum kannst du über einen String erstellen:

ausblenden Delphi-Quelltext
1:
Zahl1 := BMD_StrToBigNum('123');					

Wobei ich glaube, dass negative Zahlen nicht möglich sind (oder?)

Und deine Operation Zahl1 := Multiply(Zahl1); kann ja gar nicht funktionieren: Du übergibst für die Multiplikation nur einen Parameter. Außerdem heißt die Funktion BM_Multiply.
Pussyranger
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Di 09.08.11 18:39 
Danke für die schnelle Antwort!
Leider kann ich mit der Lib weder mit negativen noch mit Kommazahlen rechnen, oder etwa doch?
Gibt es denn sonst noch eine andere Lib, die mit den oben genannten Zahlen umgehen kann? Ich benötige nur die Rechenoperationen +,-,*.
Gammatester
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 328
Erhaltene Danke: 101



BeitragVerfasst: Mi 10.08.11 08:45 
user profile iconPussyranger hat folgendes geschrieben Zum zitierten Posting springen:
Danke für die schnelle Antwort!
Leider kann ich mit der Lib weder mit negativen noch mit Kommazahlen rechnen, oder etwa doch?
Gibt es denn sonst noch eine andere Lib, die mit den oben genannten Zahlen umgehen kann? Ich benötige nur die Rechenoperationen +,-,*.

Ja solche Libs gibt es, zB die MPArith.Bibliothek, die freie Opensource Pascal/Delphi-Quellcodes zur Verfügung stellt für Multipräzisions-Arithmetik für ganze, rationale und reelle Zahlen. Allerdings mußt Du Dich (wie auch schon bei BigNum) damit abfinden, daß ein wenig Eigenarbeit nötig ist, sprich: Man kann nicht einfach x := a*b mit großen Zahlen schreiben, sondern zB mpf_mul(a,b,x) für Fließkomma- oder mp_add(a,b,x) für Ganzahlen. Selbstverständlich werden negative Zahlen unterstützt.
Delphi-Laie
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1600
Erhaltene Danke: 232


Delphi 2 - RAD-Studio 10.1 Berlin
BeitragVerfasst: So 03.06.12 13:15 
Hallo Benny / BenBE!

Erst einmal auch von meiner Seite ein großes Kompliment für diese Unit, auf deren Grundlage ich gerade ein Langzahlrechenprogramm schreibe.

Mir sind zwei Dinge aufgefallen:

1. Hierbei geht nur um einen Kommentar: Hinter der Funktion BM_DivMod steht "Returns Int as Num1, Mod as Result". Nach meiner Beobachtung und meinen Kenntnissen ist es genau umgekehrt: In Num1 wird der Modulo und als eigentliches Funktionsergebnis der Ganzzahlanteil zurückgeliefert.

2. Ernster ist folgendes Problem: Multipliziert man die Zahl 16 mit der Funktion BM_Multiply mit sich selbst, so springt im Ergebnis derselben das interne Format vom üblichen (BigNumber) auf (0,1). bei 32 auf (0,4), bei größeren Zweierpotenzquadraten auch auf (0,0...) usw., und das anscheinend bei allen folgenden Zweierpotenzen. Auch Multiplikationen einer Zweierpotenz mit 2 sind davon betroffen.

Die Rückkonvertierungsfunktion BMD_BigNumToStr läßt sich davon nicht beirren, doch für interne Weiterrechnungen ist dieser Formatwechsel leider tödlich.

Mir fiel das auf, als ich eine schnelle Potenzierungsfunktion (auf der Basis des Binärformates des Exponenten) implementieren wollte und bei den Zweierpotenzen zu falschen Ergebnissen kam.

Auch die Funktion BM_Power scheint leider davon betroffen zu sein.

Viele Grüße

Delphi-Laie
BenBE Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 03.06.12 13:49 
Das interne Format von BigNums ist Little Endian auf Bytes. Von daher ist 16*16 = 0 * 256^0 + 1 * 256^1 korrekt. Für 32*32 = 0 * 256^0 + 4 * 256^1 stimmt das genauso. Wenn Du einmal die PowMod-Funktion anschaust, dann sollte die sogar schon auf die Art das Ergebnis rechnen.

Das andere scheint wirklich ne Implementationssache zu sein, weil in der Regel bei DivMod das Modulo-Ergebnis benötigt wird und das Div-Ergebnis in den nächsten Scheifendurchlauf einfließt.

Gruß,
BenBE.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.

Für diesen Beitrag haben gedankt: Delphi-Laie
Delphi-Laie
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1600
Erhaltene Danke: 232


Delphi 2 - RAD-Studio 10.1 Berlin
BeitragVerfasst: So 03.06.12 15:32 
Hallo Benny, bitte entschuldige, es war natürlich doch mein Fehler (den ich jetzt fand)....bei Deiner ausgereiften Unit mußte es wohl so sein.

Was der dritte Parameter Deiner PowerMod-Funktion (module) für einen Zweck hat, ist unklar. Durch Experimente fand ich heraus, daß er, auf null gesetzt, zum gewünschten Ergebnis (Potenz) führt.

Kann es sein, daß Du intern mit dem Zahlensystem zur Basis 256 arbeitest? So kommt es mir immer wieder vor, wenn ich Deinen Quelltext an unterschiedlichsten Stellen zu analysieren mich bemühe.

Ergänzung: Der Geschwindigkeitszuwachs von BigNum_Lib zu BigNum2 ist phänomenal.
BenBE Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Mo 04.06.12 17:57 
user profile iconDelphi-Laie hat folgendes geschrieben Zum zitierten Posting springen:
Hallo Benny, bitte entschuldige, es war natürlich doch mein Fehler (den ich jetzt fand)....bei Deiner ausgereiften Unit mußte es wohl so sein.

Gab es da jemals Zweifel? :twisted: 8)

user profile iconDelphi-Laie hat folgendes geschrieben Zum zitierten Posting springen:
Was der dritte Parameter Deiner PowerMod-Funktion (module) für einen Zweck hat, ist unklar. Durch Experimente fand ich heraus, daß er, auf null gesetzt, zum gewünschten Ergebnis (Potenz) führt.

PowerMod wird z.B. zum Berechnen einer Potenz in Restklassen benötigt. Also u.a. bei RSA. konkret rechnet er a^b mod n, wobei er optimiert, indem er Result := Iff (b and 1 != 0, a*PowerMod(a,b-1,n), PowerMod(a,b/2,n)^2 ) mod n;

user profile iconDelphi-Laie hat folgendes geschrieben Zum zitierten Posting springen:
Kann es sein, daß Du intern mit dem Zahlensystem zur Basis 256 arbeitest? So kommt es mir immer wieder vor, wenn ich Deinen Quelltext an unterschiedlichsten Stellen zu analysieren mich bemühe.

Ergänzung: Der Geschwindigkeitszuwachs von BigNum_Lib zu BigNum2 ist phänomenal.

Jup, ich rechne mit Basis 256. Das vereinfacht einige Dinge in Bezug auf Überläufe dramatisch.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.

Für diesen Beitrag haben gedankt: Delphi-Laie
Delphi-Laie
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1600
Erhaltene Danke: 232


Delphi 2 - RAD-Studio 10.1 Berlin
BeitragVerfasst: Di 05.06.12 07:39 
user profile iconBenBE hat folgendes geschrieben Zum zitierten Posting springen:
Jup, ich rechne mit Basis 256. Das vereinfacht einige Dinge in Bezug auf Überläufe dramatisch.


Sicher wiederholt sich jetzt wenigstens teilweise, was schon an anderer Stelle in dieser Diskussion angeregt wurde: Die Erweiterung auf einen bzw. der Wechsel zu einem 32- oder gar 64-Bit-Integertyp bietet sich an, ja, drängt sich förmlich auf; inwieweit sie aber möglich ist, kann ich natürlich nicht einschätzen. Ich machte zwar schon reichlich an Algorithmen und Quelltexten rum, die ich nicht verstand, aber mich daran zu versuchen, dürfte doch eine oder mehr Nummer(n) zu groß für mich sein.

Leider kann ich nicht erkennen, welcher Algorithmus zur Multiplikation benutzt wurde, Karazuba als Idee fiel hier ja schon. Ich werfe einfach noch die russische Bauernmultiplikation ein. Ja, und dann noch FFT, das nach meinem Wissen Hagen Redmann für sein DEC benutzt. Aber das ist Dir sicher alles bekannt.

Eine meinerseits "handgeschriebene" schnelle Potenzierung ist sogar etwas schneller als Deine oben erwähnte, allerdings wird dabei nicht mit einem Rest (Modulo) hantiert, so daß sie für Ver-/Entschlüsselungen nicht geeignet sein dürfte.

Und beim BigNum_Lib wird bei der Funktion BigNumToStr das Argument verändert, was Ausgaben während der Rechnung(en) unmöglich macht, wenn man den Wert noch weiter benötigt. Ich versuchte es auch schon mit Übergaben an Dummywerte, mit denen ich dann die Funktion fütterte, doch auch hier wird das Original verändert, so, als sei das alles nur eine Datenstruktur und die Variablen letztlich nur Zeiger darauf. Seltsam...

Viel Spaß und Erfolg bei der weiteren Optimierung, und versuche bitte, Delphi-4-kompatibel zu bleiben!
Delphi-Laie
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1600
Erhaltene Danke: 232


Delphi 2 - RAD-Studio 10.1 Berlin
BeitragVerfasst: Mi 06.06.12 11:52 
Hallo Benny!

In der Funktion BMD_FractionToStr wird eine - m.E. unnötige - fehlende Initialisierung der Variable "Digit" bemängelt. In der Funktion BM_Modulo hingegen ist eine Initialisierung (Einnullung) der Variable result am Funktionsanfang, spätestens am Anfang des ersten If-Blockes hingegen anscheinend nötig (kann bei großen Zahlen zu Fehlfunktionen führen), wird dort jedoch nicht als fehlend moniert. Alles weitere ausführlich in meiner PM mit Testprogramm.

Fazit: Hervorragende Unit, die durch unser aller Hilfe noch den letzten Feinschliff bekommt.
Delphi-Laie
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1600
Erhaltene Danke: 232


Delphi 2 - RAD-Studio 10.1 Berlin
BeitragVerfasst: Sa 09.06.12 12:31 
In der Funktion BMD_BigNumToStr steht

ausblenden Delphi-Quelltext
1:
If Result = '' Then Result := '0';					


nur im if-Teil für die Hexausgabe, Dezimalzahlen werde so nicht mit erfaßt. Es sollte deshalb auch im else-Teil oder - noch besser - einfach am Ende der Funktion placiert werden.