DIV and MOD
Liste der Anhänge anzeigen (Anzahl: 2)
Guuuuuten Tag!
ich habe seit gestern ein wenig mit den Ausdrücken DIV und MOD experimentiert und heraus kam eine dll. sie hat zwar wenig nutzen weil man das alles auch mit strings machen könnte aber trotzdem erklär ich mal ein paar methoden: -GetDig -> sucht eine Ziffer in einem Integer -GetLastDig -> gibt die letzte Ziffer zurück -ChangeDig -> ändert Ziffer a in Zahl b zu Ziffer c um -TrimDeg -> versucht einen Winkel möglichst klein zu machen:
Delphi-Quellcode:
-TrimRad -> Das gleiche
begin
X := 850; // X = 850 TrimDeg(X); // X = 130 end;
Delphi-Quellcode:
ihr seht ja schon, dass das ganze hauptsächlich irgendwas mit ziffern macht
begin
X := 5.2; // X = 5.2 TrimRad(X); // X = 1.2 Bitte guckt es euch an und sagt mir, wenn ihr Fehler entdeckt. Bittedankeschön [edit=Luckie]Thread-Titel korrigiert, als ein Wort findet man das ja in der Suche nie. :wall: Mfg, Luckie[/edit] |
Re: DIVandMOD
fast 90kb für so eine DLL? :shock:
Warum ist das meiste eine Procedure und keine Funktion? |
Re: DIVandMOD
zu der größe kann ich nix sagen, meinee erste dll.
das meiste ändert ja zahlen also procedure. Inc ist auch eine prozedur oder? ne idee wegen der größe an was das liegen könnte? |
Re: DIVandMOD
Versuch mal so viel wie möglich aus den Uses rauszuschmeißen, falls noch nicht geschehen ;-)
|
Re: DIVandMOD
math brauch ich für power
sysutils und classes waren schon drin das wars. brauch ich classes nicht? |
Re: DIVandMOD
-classes brauchst du nicht
-wenn du inttostr durch die Prozedur "str" ersetzt, dann fällt auch sysutils raus -da power bei dir nur mit natürlichen zahlen rechnet, kannst du auch math rausschmeissen und power durch eine forschleife o.ä. ersetzen Edit: z.B. dadurch kannst du alle Bibliotheken rausschmeissen
Delphi-Quellcode:
Es lohnt sich nicht, wegen zwei so läppischen Funktionen, den ganzen Balast dieser Units mitzunehmen (die math bindet wiederum die sysutils ein)
function inttostr(x:integer):string;
begin str(i,result); end; function power(x,y:integer):integer; var i:integer; begin result:=1; for i:=1 to y do result:=result*x; end; Edit2: Ansonsten finde ich es etwas übertrieben, sowas hier reinzustellen. 1. Der QC haut ja nun keinen vom Hocker. Sowas hat doch 99% der Pascal-Nutzer innerhalb von wenigen sekunden, ohne groß nachzudenken geschrieben 2. Würde ich dafür nicht extra eine DLL hochladen. ==> Es ist sicherlich schön und sehr gut für dich zum üben :zwinker: , aber man muss nicht jeden "Furz" veröffentlichen. Und Letztens: Warum nimmst du stdcall? Gerade bei den Funktionen lohnt sich ja register erst. |
Re: DIVandMOD
Statt Proceduren solltest du Funktionen benutzen, wenn man beispielsweise nur wissen möchte, was rauskommt ohne gleich die gesamte Variable zu ändern, zB
Delphi-Quellcode:
if TrimRad(x)>5 then
|
Re: DIVandMOD
OK! ich hab das jetzt mal mit Funktionen erweitert. siehe erster Post :mrgreen:
|
Re: DIVandMOD
und wie groß isse nun die dll?
|
Re: DIVandMOD
88 Kilo wenn man der delphipraxis glauben schenkt :mrgreen:
|
Re: DIVandMOD
wenn du die sysutils noch raus kickst aus der uses section,
dann sparst du noch mal 8 kb, also insgesamt dann 80 kb. du musst dann halt nur noch die funktion inttostr aus den sysutils in deine dll kopieren... |
Re: DIVandMOD
Warum eigentlich eine DLL? Eine normale Unit würde es doch auch tun. Und wenn du den Quellcode nicht herausgeben willst, kannst du ja auch immer noch nur die DCU herausgeben. Ich finde eine DLL für sowas, was eigentlich nur Spielerei ist, total übertrieben.
Christopher |
Re: DIV and MOD
spielerei, darum geht es ihm ja denke auch.
jeder fängt mal klein an oder? |
Re: DIVandMOD
Zitat:
mein code is ja dabei und eigentlich wollt ich nur mal sehen ob das bei mir als dll überhaupt klappt |
Re: DIV and MOD
Du darfst nicht nur die Funktionen ergänzen, sondern musst auch die Unist aus der uses-Liste entfernen. Die tauchen in deiner DLL noch auf.
Ich hatte es unter 20kb. Wobei der Vorteil noch dadurch vergrößert wird, dass nicht unnötig Klassen (z.B. Exception) durch die Units instanziert werden. |
Re: DIVandMOD
Zitat:
a^b = (e^ln a)^b = e^(b * ln a) |
Re: DIVandMOD
Zitat:
|
Re: DIV and MOD
@Khabarakh: Aha!! - Das versteh ich nicht...
@sirius: ich glaub ich lass es jetzt einfach is auch egal |
Re: DIV and MOD
Ich dachte du wolltest dazulernen :zwinker:, dafür sind wir doch hier :dp:
Was K. gemeint hat, kommt aus den Logarithmengesetzen. Ist keine Zauberei. (und wenn du 13 bist, dann hab Geduld, das kommt noch in der Schule). So macht es auch die Unit math. Bzw. so hat man es früher selber implemtiert als man noch keine Unit math hatte. Damit kann man quasi x^y für alle reellen Zahlen (mit x>0) rechnen. günstiger für die FPU wäre IMHO x^y = 2^(x*lb(a)). Aber für deine Anwendung ist das alles overkill. Vermeide Fleißkommazahlen (single,double,real,extended) solange es geht! |
Re: DIV and MOD
ja ich will auch lernen aber ich finde die sysutils.pas nicht^^
außerdem fällt mir nichts mehr ein was ich noch machen könnte weil auf optimierung hab ich keine lust wenn es nur ums lernen geht^^ nochwas: meinst du nicht Fließkommazahl? was ist schneller? Mein ChangeDig oder irgendwas mit strings und inttostr? |
Re: DIV and MOD
Ja meine ich...
Stringoperationen sind nicht die schnellsten, ... hmm schwer da ne Aussage zu treffen. Das müsste man testen. |
Re: DIV and MOD
[OT]
Zitat:
[/OT] @dajuhsa: Vielleicht bin ich in der Minderheit, aber ich würde als 1. Ziffer jene am Weitesten rechts bezeichnen, da ihre Wertigkeit die niedrigste ist. Vor allem aber sparst du dir mit dieser Zählweise den IntToStr-Aufruf ;) (den man sowieso wieder durch einen eleganteren Logarithmus ersetzen könnte, aber das nur am Rande; denn in Punkto Performance ändert sich nichts). |
Re: DIV and MOD
Zitat:
Zitat:
Trotzdem ist man wenn man 10^N (im Bereich integer) rechnet, mit einer For-Schleife oder besser noch mit einem vorbelegten array besser dran (wenn man schon abkürzen will) |
Re: DIV and MOD
Hi @ all,
ich habe mich auch mal mit dem Thema auseinader gesetzt und habe eine "IntLength"-Funktion entworfen, welche ohne strings die Länge eines Integers bestimmen kann.
Delphi-Quellcode:
Ich habe mal ein Test gemacht: Bei mir braucht die string-Variante für 900.001 Durchläufe ~ 255 ms. Die IntLength-Variante jetzt schon nur ~ 188 ms.
function IntLength(AInt : Integer) : Integer;
begin Result := 0; while AInt > 0 do begin AInt := AInt div 10; inc(Result); end; end; Vielleicht kennt ihr eine Möglichkeit den obigen Code zu optimieren ;) Vielleicht mit ASM? Da müsste ich aber passen :) da für mich ASM im FoW liegt xD Zusätzlich hier meine ExtLength-Variante:
Delphi-Quellcode:
Sie berechnet leider nicht die Nachkommastellen, allerdings weiß ich nicht ob man die mitdazu rechnet.
function ExtLength(AExt : Extended) : Integer;
begin Result := IntLength(Trunc(AExt)); end; Ich werde mir mal überlegen wie man das hinkriegen könnte. [edit]Ich habe mir jetzt mal überlegt: Ich könnte die Vorkommastellen abschneiden und dann solange multiplizieren bis ich keine Nachkommastellen mehr habe. Also habe ich das so gelöst:
Delphi-Quellcode:
Das Problem scheint zu sein, dass ABuf nicht genau eine Ganzzahl ist. Deshalb klemmt er sich da in eine Endlosschleife. (Wenn Trunc(ABuf) = 87 und ABuf 87 ist, beendet er nicht die Schleife)[/edit]
{ Returns the length of a float (e.g. ExtLength(4365.87) = 6) }
function ExtLength(AExt : Extended) : Integer; var ABuf : Extended; begin Result := IntLength(Trunc(AExt)); ABuf := AExt - Trunc(AExt); while Trunc(ABuf) < ABuf do begin ABuf := ABuf * 10; inc(result); end; end; MfG xZise PS: string: ~437 ms; extLength: ~250 ms |
Re: DIV and MOD
Die Länge der Nachkommastellen kannst du nicht wirklich ermitteln, da du dort bei so gut wie jedem Wert auf eine Periode stoßen wirst - schließlich untersuchst du die Zahl zur Basis 10, gespeichert wird sie aber zur Basis 2. Du müsstest die Zahl erst in einem sinnvollen Maße runden, genau so, wie es FloatToStr macht.
[edit]Du kannst ja noch den mathematischen Weg testen. Wird wohl irgendwo zwischen den beiden anderen Methoden liegen.
Delphi-Quellcode:
[/edit]
function IntLength(const aInt : Integer) : Integer;
begin Result := Ceil(Log10(aInt)); // bzw. Trunc(Ln(aInt) / Ln(10)) + 1 end; |
Re: DIV and MOD
Zitat:
Und das Ceil ist ja nichts anderes als "Trunc() + 1" oder? Meine Frage ist, wo kann man den Logaritmus so optimieren (in richtung Log10) gegenüber ln? Weil an sich machen ja beide das gleiche (Also das bei Ceil() und Trunc()). Und zu den Extended: Da müsste man sich also mit den Vorkammastellen zufriedengeben... Oder? [edit]Ehm... Trunc() + 1 ist bis zu 100 ms schneller als Ceil() o.O
Delphi-Quellcode:
Das ist der gewinner mit nur 79 ms um 900.000 berechnungen durchzuführen![/edit]
function IntLength3(const aInt : Integer) : Integer;
begin Result := Trunc(Log10(aInt)) + 1; // bzw. Trunc(Ln(aInt) / Ln(10)) + 1; end; [edit]Wenn man nur die Log10()-Methode aus der math.pas kopiert funktionierts auch ohne uses. Aber ich glaube Borland sieht das nicht gerne oder? Vielleicht könnte man es legalisieren?[/edit] |
Re: DIV and MOD
Hi,
Zitat:
Mfg FAlter |
Re: DIV and MOD
Zitat:
Zitat:
Zitat:
Zitat:
|
Re: DIV and MOD
Zitat:
Ob log10 schneller als ln ist, weiß ich nicht. Aber es gilt ja:
Code:
Also müsste man sagen: Das "ln"-Konstrukt ist langsamer als log10 liefert aber gleiche Ergebnisse. Und rein theoretisch müssten beide Operatioen gleich schnell ablaufen, da ich, um log10 zu simulieren, das "ln"-Konstrukt verwenden würde.
log10(X) = ln(X) / ln(10)
Aber den scheint nicht so zu sein, oder Borland hat den log10-Algorythmus optimiert, weil ja die... ehm Basis? ... immer gleich ist, und man irgendwo kürzen könnte. Ich weiß aber nicht, ob sie auch einfach ein anderen Rechenweg verwenden. Wegen Lazarus/OpenPascal: Ich besitze es nicht :) und kann deshalb auch keine aussage darüber machen. Und nur deshalb das zu downloaden wäre etwas zu overkill :) Vielleicht gibt es jemand anderen, der den log10-Algorythmus posten kann. Ich könnte den in den Testprogramm integrieren. MfG xZise [edit]omfg ... sry, aber es steht ja als Kommentar da:
Delphi-Quellcode:
Meine, zwar noch auf math basieren, aber ggf. bald nicht mehr:
{ Log.10(X) := Log.2(X) * Log.10(2) }
Delphi-Quellcode:
[/edit]
function Log10(const X : Extended) : Extended;
begin Result := Log2(X) * LogN(10, 2); end; |
Re: DIV and MOD
Zitat:
Code:
Und nun? Das kann man immer weiter fortsetzen mit jeder beliebigen Basis
ln(x)=log10(x) / log10(e)
Es geht doch in dem Fall darum, was die FPU am schnellsten kann. Du hast neben den 4 Grundrechenoperationen folgendes zur Verfügung: - a * log2(b) - (2^a) - 1 für -1 <= a <= +1 - a*2^(int(b)) Und natürlich noch runden, trigonometrische Funktionen und noch folgende Konstanten: - pi - log2(10) - log2(e) - log10(2) - ln(2) Edit: Demnach bekommt man log10 und log2 recht schnell hin und für alle anderen Basen braucht man die doppelte Zeit. Edit: ln auch :mrgreen: |
Re: DIV and MOD
Allerdings sind Divisionen langsamer als Multiplikationen.
Deshalb ist (wahrscheinlich) die Multiplikationsvariante schneller... Es geht nur darum die Unit math rauszuhauen. |
Re: DIVandMOD
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:42 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