Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Software-Projekte der Mitglieder (https://www.delphipraxis.net/26-software-projekte-der-mitglieder/)
-   -   Programm Wurzelberechnung nach Heron (https://www.delphipraxis.net/191426-programm-wurzelberechnung-nach-heron.html)

EdAdvokat 14. Jan 2017 12:47

Programm Wurzelberechnung nach Heron
 
Liste der Anhänge anzeigen (Anzahl: 1)
Eine kleine Spielerei für mathematisch Interessierte. Sicher gehörend zur Kategorie: "Dinge, die die Welt nur selten braucht".
Es handelt sich um eine iterative Berechnung(Annäherung) zur Bestimmung von Wurzeln mit verschiedener Wurzelexponenten.
Das Heron-Verfahren für die Berechnung der 2-ten Wurzel wurde vermutlich in der Schule gelehrt, jedoch läßt sich diese Formel
auch auf Wurzeln mit größerem Wuzelexponent erweitern.
Ich stelle das kleine Programm der Kritik der User des Forums und bin für Anregungen und Verbesserungsvorschläge dankbar.
Entstanden ist das Ganze aus einer Aufgabenstellung zum Erlernen von Delphi (Uni Leipzig) zunächst mit der Umsetzung der 2-ten Wurzel
und der Maßgabe, wer möchte könne als Zusatzaufgabe auch ein Programm entwickeln für die n-te Wurzel. Dazu habe ich einige Zeit
gebraucht und die Hilfe des Internet in Anspruch genommen, um die entsprechende Formel zu finden. Danach entstand zunächt ein
prozedurales Programm zur Berechnung von Wurzeln nach Heron, dass nunmehr objektorientiert weiterentwickelt wurde.
Ich hoffe es macht ein wenig Spaß damit zu experimentieren und warte auf Reaktionen.:!:

Delphi-Laie 14. Jan 2017 19:58

AW: Programm Wurzelberechnung nach Heron
 
Interessantes kleines Programm, danke! Es ist immer wieder erstaunlich, zu welchen Hochleistungen die Hochkulturen schon der Antike und sogar Präantike imstande waren.

Ich hätte nur kleine Dinge anzumerken:

1. Man kann beim Startwert kein "-" eingeben, auch kein "." oder ",", die Fehlermeldung meint jedoch, man könne dort nur Zahlen eingeben. Negative und Fließkommazahlen sind jedoch auch welche. Entweder kann man nur Ziffern oder natürliche Zahlen eingeben, das meinte diese Fehlermeldung eigentlich. Immerhin müßte der Startwert intern, jedenfalls nach untenstehender Formel, eine Fließkommazahl sein, warum also darf der eingebbare Wert nicht auch eine solche sein?

2. Der Term "1/n" beim Startwert in der Formel(darstellung) kann weggelassen und stattdessen sein Nenner, das "n", einfach in den zweiten Nenner multiplikativ übernommen werden.

3. Sprachliche Unsauberkeiten, nur einige davon:
- "Zahl der Durchläufe" (genaugenommen Anzahl)
- "reele" (oben)
- "Potenziern d. Ergebnis" (Info)
- "ausbaufähig" (Info)

EdAdvokat 15. Jan 2017 10:03

AW: Programm Wurzelberechnung nach Heron
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo zusammen, Danke für die Hinweise von Delphi-Laie. Ich hoffe, sie exakt berücksichtigt zu haben.
Zusätzlich habe ich noch einige kleine Änderungen vorgenommen. Es können nunmehr auch Dezimalpunkt und Komma im Feld Startwert eingegeben werden.(Für ein Minuszeichen sehe ich keine Veranlassung,denn dies führt zu negativen Ergebnissen)

EdAdvokat 15. Jan 2017 14:11

AW: Programm Wurzelberechnung nach Heron
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo, aufgrund verschiedener Hinweise zu einem anderen Projekt habe ich das Programm "Heron" nochmals korrigiert und die globale Variable als FHeron im Formular unter private deklariert.
Auch die Werteinitialisierung wurde verändert. Ich hoffe so ist es besser. Nun bin ich am Grübeln nach neuen Programmideen, die ich mit meinem gegenwärtigen Wissensstand verwirklichen könnte. Auch für derartige Anregungen wäre ich dankbar. :idea:

Delphi-Laie 15. Jan 2017 21:48

AW: Programm Wurzelberechnung nach Heron
 
Zitat:

Zitat von EdAdvokat (Beitrag 1358875)
Nun bin ich am Grübeln nach neuen Programmideen, die ich mit meinem gegenwärtigen Wissensstand verwirklichen könnte. Auch für derartige Anregungen wäre ich dankbar. :idea:

Deinen aktuellen Wissensstand kennst Du (selbst) am besten. Doch ist es nicht ein wenig langweilig, sich vom eigenen Wissensstand vorschreiben zu lassen, was man programmiert und was nicht? Sind das Anspruch und Herausforderung genug, die reizen?

Nähkasten: Ich habe mich nie darum geschert, was ich kann und vor allem, was nicht. Was ich zu realisieren beabsichtigte, ging ich an bzw. nahm ich in Angriff, i.d.R. mit akzeptabler Erfolgsquote, sonst hätte ich diese Leidenschaft an den Nagel gehängt. Vieles lernte ich "by doing" so nebenbei. Zum Glück gibt es Bücher, Internetseiten und bei letzteren vor allem die Foren, wo man nicht nur schmökern und stöbern, sondern auch fragen kann. Meistens wird einem rasch, fundiert und freundlich geholfen - dafür auch an dieser Stelle nochmals danke! Dabei bin ich nie ein OOP- oder gar Assembler-Experte geworden, aber das war auch beileibe nicht mein Ziel, sondern das Problemlösen mithilfe eines Programmes.

Also - was interessiert Dich? Welches Pogramm benötigt zwar die Welt nicht, aber Du hingegen vermißt es mehr oder weniger schmerzlich? Wenn Dir etwas einfällt, dann nur zu!

Bjoerk 16. Jan 2017 10:07

AW: Programm Wurzelberechnung nach Heron
 
Da du jetzt "Master of Heron" bist, würde sich eine Ergänzung anbieten: Schriftliches Wurzelziehen. Dabei würdest zum Beispiel etwas über Strings lernen.

EdAdvokat 16. Jan 2017 15:00

AW: Programm Wurzelberechnung nach Heron
 
Na Master of Heron:-D ist wohl etwas zu hoch gegriffen, doch die Berechnung hat mich gereizt und so ist das Spielerchen entstanden. Der Link zu den verschiedenen Möglichkeiten zur Berechnung einer Wurzel ist interessant und möglicherweise eine Anregung für ein weiteres Programm, was die Welt nicht unbedingt braucht.
Ich suche nach Programmideen, nachdem ich hier im Forum bereits eine Warenberechnung (Programm Waren) und den Verkauf von Kinokarten (Programm Kinokarten) vorgestellt habe. Bei der Realisierung dieser Programme konnte ich eine Reihe von Anregungen umsetzen und habe dabei viel dazugelernt.
Ich will keineswegs auf der Stelle treten. Da habe ich mich wohl etwas unglücklich ausgedrückt. Natürlich soll jedes neue Projekt wieder eine Herausforderung sein, doch das "Projekt" sollte im Rahmen bleiben und nicht ausufern. Die Aufgaben verschiedener Schulen/Hochschulen zum Erlernen von Objekt-Pascal sind recht interessant und ich habe viele davon bereits durchgearbeitet. Evtl. gibt es da noch mehr.
Diverse Kryptologieprogramme, Editoren und math. Berechnungen habe ich auch bereits nachempfunden, doch all das ist bereits vorhanden und hinreichend erklärt worden.
Ich werde also weitergrübeln und die Foren durchstreifen. Wenn jemand eine Idee haben solle, wäre ich dafür dankbar.:!:

Jumpy 16. Jan 2017 15:17

AW: Programm Wurzelberechnung nach Heron
 
Gibts zwar auch zur genüge, aber wenn du mal eine Datenbank-Anwendung machen willst, um mal was in dem Themenbereich zu lernen, wie wäre es damit:

- Vereinsverwaltung
- Bibliotheksprogramm (Bücher ausleihen usw.)
- Adressverwaltung

Bjoerk 16. Jan 2017 15:23

AW: Programm Wurzelberechnung nach Heron
 
Norbert, deine Einstellung gefällt mir. Ich wünsche Dir viel Erfolg!

Delphi-Laie 16. Jan 2017 16:38

AW: Programm Wurzelberechnung nach Heron
 
Zitat:

Zitat von Bjoerk (Beitrag 1358974)
Norbert, deine Einstellung gefällt mir. Ich wünsche Dir viel Erfolg!

Mir auch, und wünsche ich ebenso!

Zitat:

Zitat von EdAdvokat (Beitrag 1358971)
und habe dabei viel dazugelernt.
Ich will keineswegs auf der Stelle treten. Da habe ich mich wohl etwas unglücklich ausgedrückt. Natürlich soll jedes neue Projekt wieder eine Herausforderung sein,

Sei Dir aber eines gewiß: Gelernt und dann nur die Früchte der Arbeit zu ernten, ist heutzutage so nicht mehr möglich. Informationstechnik ist eine der am schnellsten wachsenden und sich vor allem fortentwickelten technologischen Bereiche. Sogar für Hobbyprogrammierer, die keinem Zwang ausgesetzt sind (außer vielleicht ihrem eigenen Antrieb), ergibt sich nahezu ständig neues. Sogar die Berufsinformatiker dieses Forums werden vielleicht manchmal den ständigen Lernzwang als belastend empfinden.

Zitat:

Zitat von Bjoerk (Beitrag 1358974)
doch das "Projekt" sollte im Rahmen bleiben und nicht ausufern.

Das weiß man vorher nicht, erst hinterher ist man schlauer. Wenn man etwas mit Interesse, Enthusiasmus und Akribie betreibt und verfolgt, hat nahezu alles das Potential zu einer unendlichen Geschichte. Ich erwähne nur mal Mathematikalpha und den Hexeditor, in einem Nachbarforum "Nemp". Auch Luckie hat viele Jahre an seinem XP Usermanager herumprogrammiert. Alle Projekte haben eine beachtliche Funktionsfülle und Reife erreicht.

EdAdvokat 16. Jan 2017 16:58

AW: Programm Wurzelberechnung nach Heron
 
Mathematikalpha ist ein beeindruckendes Mamutprogramm. Dafür sollte eine "Schulpflicht":) eingeführt werden. Ich ziehe den Hut vor Steffen Polster, dem Autor des mit Delphi 5 geschriebnen Programms.
Auch einige Projekte und Veröffentlichungen von Luckie habe ich angesehen und bin der Auffassung, dass geballtes Wissen zu Delphi, besser zu Objekt-Pascal hier vorhanden ist und leider die Literatur auf diesem Gebiet sehr schwach ist. Ich wünschte, es würden sich einige Füchse zusammenfinden und ein Werk "Tipps und Tricks", wie es vormals im C&L Computer und Literaturverlag Böblingen verlegt wurde herausbringen, dass Delphe 10.1 einschließt und vor allem auf Programmiertechniken konzentriert sein sollte. Ich denke ein Bedarf dazu ist vorhanden zumal es diesbezüglich fast nichts
mehr gibt.
Ich danke für die Anregungen und werde weiter grübeln.

madas 17. Jan 2017 12:57

AW: Programm Wurzelberechnung nach Heron
 
Unten im Formelfenster gibt es entweder eine "(" zu wenig oder die ")" nach Radikant ist zu viel.

EdAdvokat 17. Jan 2017 14:19

AW: Programm Wurzelberechnung nach Heron
 
Weder Delphi meckert in irgendeiner Form noch kann ich selbst keine Klammer zuviel oder zu wenig erkennen.
in der Formel:
Delphi-Quellcode:
  FStartwert:= 1/FExpo * ((FExpo-1)*Power(FStartwert,FExpo)+FRadikant)/Power(FStartwert,FExpo-1);
werden 4 Klammern geöffnet und auch 4 wieder geschlossen.
Gib doch bitte den genauen Abschnitt ein, den Du meinst.

nahpets 17. Jan 2017 16:22

AW: Programm Wurzelberechnung nach Heron
 
Zitat:

Zitat von madas (Beitrag 1359052)
Unten im Formelfenster gibt es entweder eine "(" zu wenig oder die ")" nach Radikant ist zu viel.

Im Formular:
Delphi-Quellcode:
    object Label11: TLabel
      Left = 17
      Top = 27
      Width = 463
      Height = 13
      Caption =
        'Startwert := 1/Expo * (Expo-1) * power(Startwert, Expo)+Radikant' +
        ')/power(Startwert,Expo-1);'
    end
Programmidee:

Ich hätte bitte gerne eine Uhr, die mir die Uhrzeit und das Datum (sekundengenau, also nicht einmal irgendwann innerhalb einer Sekunde, sondern pünktlich zum Beginn jeder Sekunde) in römischen Ziffern anzeigt.

In Düsseldorf steht ein Fernweldeturm mit Uhr.

Soeine hätte ich bitteschön gerne. Sie sollte sich senkrecht an den rechten Bildschirmrand legen und zwar so, dass die darunterliegenden Programme nicht vollständig überdeckt werden, sondern bedienbar bleiben. (Genauigkeit wie oben.)

Dann noch was anspruchsvolles:

Es gibt ja diverse Programme, mit denen man (Text-)Dateien vergleichen kann.
Hier hätte ich bitte gerne Eines, welches beim Textvergleich auch dann noch eine eindeutige Übereinstimmung von Textpassagen feststellen kann, wenn eine Datei in der alten und eine in der neuen Rechtschreibung vorliegt.
Diverse Buchstabendreher und sonstige kleiner Schreibfehler sollten dem Auffinden von Übereinstimmungen nicht im Weg stehen.

Genug Ideen: ff beim Umsetzen ;-)

Abkürzungsverzeichnis:
ff: fiel fergnügen ;-)

EdAdvokat 17. Jan 2017 16:53

AW: Programm Wurzelberechnung nach Heron
 
Liste der Anhänge anzeigen (Anzahl: 1)
Danke für den konkreten Hinweis. Habe ich verändert. Danke auch für die Anregungen. Da habe ich wohl einiges zu tun.

EdAdvokat 18. Jan 2017 15:50

AW: Programm Wurzelberechnung nach Heron
 
Liste der Anhänge anzeigen (Anzahl: 1)
Also Stephan(nahpets), nicht das es schon fertig wäre, doch will ich die ersten Studien zum Thema Uhrzeit in roemischen Zahlen kurz vorstellen.:)

nahpets 18. Jan 2017 16:16

AW: Programm Wurzelberechnung nach Heron
 
Also ehrlich, diese Bedingung ist noch nicht erfüllt:
Zitat:

(sekundengenau, also nicht einmal irgendwann innerhalb einer Sekunde, sondern pünktlich zum Beginn jeder Sekunde)
Die Millisekunden sind nie 0, sondern immer (während der Programmlaufzeit) eine annähernd gleichbleibende Zahl <> 0.
(Erhöht sich pro Minute um ca. 2 bis 3 Millisekunden.)

D. H.: Die Zeit wird nach jeweils einer Sekunde aktuallisiert, aber nicht zum Beginn der Sekunde, sondern "mitten drin" ;-)

Da der Timer von Delphi nur eine kleinste Auflösung von einer Millisekunde hat, sei hier ein Fehler von +/- einer Millisekunde akzeptiert. ;-)

ff

Jumpy 18. Jan 2017 16:57

AW: Programm Wurzelberechnung nach Heron
 
Zitat:

Zitat von nahpets (Beitrag 1359189)
Da der Timer von Delphi nur eine kleinste Auflösung von einer Millisekunde hat, sei hier ein Fehler von +/- einer Millisekunde akzeptiert. ;-)

Dies ist aber sehr großzügig :-D

nahpets 18. Jan 2017 17:01

AW: Programm Wurzelberechnung nach Heron
 
Zitat:

Zitat von Jumpy (Beitrag 1359193)
Zitat:

Zitat von nahpets (Beitrag 1359189)
Da der Timer von Delphi nur eine kleinste Auflösung von einer Millisekunde hat, sei hier ein Fehler von +/- einer Millisekunde akzeptiert. ;-)

Dies ist aber sehr großzügig :-D

Ja, geht aber ;-)

EdAdvokat 18. Jan 2017 17:07

AW: Programm Wurzelberechnung nach Heron
 
da bin ich erst einmal platt, denn zwischenzeitlich habe ich den Düsseldorfer Fernsehturm ins Formular bekommen und auch die entsprechende Durchsicht auf ein darunter liegendes Formulare hinbekommen mit den roemischen Anzeigen auf dem Rumpf des Turmes und glaubte mich fast am Ziel.
Doch wie ich diese geforderte Genauigkeit hinbekommen könnte ist mir überhaupt nicht klar, denn ich dachte das klappt über den Timer von Delphi mit der gegenwärtigen Einstellung. Kann mir da ein Wink gegeben werden?

nahpets 18. Jan 2017 17:17

AW: Programm Wurzelberechnung nach Heron
 
Na klar kann ich 'nen Tipp geben.
Sonst hätt' ich ja nicht 'ne so blödsinnige Forderung gestellt.

Am Beginn des Timerereignisses diesen ausschalten.
Arbeit machen.
Zeit bis zur nächsten vollen Sekunde berechnen.
Timerintervall entsprechend setzen.
Timer einschalten.

Achso: Für die Zeitangaben reicht aber eigentlich ein Timer aus.
Und die Zeit sollte man im Laufe der Ereignisabarbeitung nicht mehrfach auslesen, es könnten dann (marginale) Abweichungen auftreten ;-)

EdAdvokat 18. Jan 2017 18:03

AW: Programm Wurzelberechnung nach Heron
 
ich stehe im winterlichen Nebel(also es ist kalt und ich sehe keinen Horizont) und nirgends ist ein blinkender Fernsehturm erkennbar. Also die Hinweise zum Timer (nur einen) habe ich berücksichtigt.
Doch was ich ggf. berechnen sollte ist mir überhaupt nicht klar. Ich habe nicht einmal einen Ansatzpunkt, worüber ich nachdenken könnte.
Am Beginn des Timergerg. Timer aus; wo genau? Arbeit machen? welche denn? Zeit bis zur neuen Sec berechnen? wie das den bitte? Dementsprechend Timerintervall setzen; wäre schön, wenn ich da angekommen wäre! Timer anstellen, das würde mir sicher gelingen mit Timer.enabled:=true das ist wohl das einzige was ich an dieser Stelle könnte, doch den Timer ausschalten könnte ich wohl auch.
Es ist mir auch wirklich nicht klar, was konkret unabhängig von der Programmierung, die Aufgabe an dieser STelle ist. Das Ding läuft doch so vor sich hin und zeigt die Zeit sogar in roemischen Zahlen!

nahpets 18. Jan 2017 18:58

AW: Programm Wurzelberechnung nach Heron
 
Also, damit ein Timer arbeitet, muss irgendwo Enabled auf True gesetzt worden sein. Das kann im Objektinspektor sein oder im Quelltext.

Im Timerereignis nun zu beginn den Timer ausschalten, also Enabled auf false.

Jetzt wird ja allerlei im Ereignis gemacht. Zeit ermitteln, in römische Zahlen umwandeln, zur Anzeige bringen ...

Dabei vergeht ja etwas Zeit. Bis zur nächsten vollen Sekunde (für die nächste Anzeige ...) besteht nun noch eine Zeitdifferenz von x Millisekunden (> 0 und < 999).
Das Timerintervall ist im Objektinspektor (vermutlich) auf 1000 gesetzt. Die verbleibende Zeit bis zur nächsten vollen Sekunde ist aber nicht immer 1000 Ms. Daher muss hier die Zeitspanne zwischen Jetzt und der nächsten vollen Sekunden berechnet werden. Dieser Wert muss dann dem Timerintervall zugewiesen werden und anschließend Enabled wieder auf True gesetzt werden.

Warum reite ich auf dem ganzen (hier im konkreten Fall) Quatsch rum?

Stell' Dir vor, Du musst in regelmäßigen Abständen eine bestimmte Aufgabe erledigen. Z. B. genau zu jeder vollen Minute. Aber es kommt erschwerend hinzu: Unter bestimmten, ungünstigen, Bedingungen dauert die Erledigung der Aufgabe länger als eine Minute. Ein permanent laufender Timer, der stoisch alle 60000 MS "zuschlägt", würde also die Timerroutine bereits aufrufen, während die vorherige noch abgearbeitet wir. Das sollte verhindert werden.

Da nicht bekannt ist, wie lange nun die Abarbeitung der Aufgabe in jedem Einzellfall dauert, kann man hier also nicht mit einem statischen Timerintervall arbeiten.
Am Ende der Aufgabe muss also die Anzahl der Millisekunden bis zur nächsten vollen Minute berechnet werden, das Timerinterval entsprechend gesetzt werden und dann der Timer aktiviert werden.

Oder mal einfach so als Spasserweiterung für Deine Uhr.

Der Timer setzt jede Sekunde "Alles". Das Datum ändert sich aber nur einmal täglich.

Dafür könnte man auch einen Timer nehmen. Beim Programmstart wird die Timerroutine einmal aufgerufen und dort wird dann die verbleibende Zeit in Millisekunden bis 0 Uhr berechnet, das Timerintervall gesetzt und der Timer eingeschaltet.
Damit wird das Datum nur noch einmal täglich um 0 Uhr gesetzt.
Nimm einfach mal an, dass Du da nicht einfach nur Text auf ein Label schreibst, sondern über eine Schnittstelle eine große mechanische Anzeigetafel ansteuern musst, dann ist es schon eine Überlegung wert, ob man das wirklich jede Sekunde macht oder nur wenn sich das Datum ändert.

Als Spielerei könnte man jetzt ja auch noch einen Timer nehmen, der nur für die Anzeige der vollen Stunde zuständig ist.

Und einen, der nur für die Anzeige der vollen Minuten zuständig ist.

Und als letztes den für die Sekunden.

Klar ist das für 'ne einfach Uhr völlig überdimensioniert, aber mal mit Zeiten rechnen und Zeitdifferenzen ermitteln, um damit ein bestimmtes, in der Zukunft liegendes, zu einem konkreten Zeitpunkt auszulösendes, Ereignis in Gang zubringen, ist schon 'ne Lernaufgabe ;-)

EdAdvokat 18. Jan 2017 20:22

AW: Programm Wurzelberechnung nach Heron
 
ich habe die Zeitdifferenz gesondert gemessen. Sie beträgt 0 ms.

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  Present: TDateTime;
  Year, Month, Day, Hour, Min, Sec, MSec: Word;
  Zeit : String;
  startTime: Cardinal;
begin
  timer2.Enabled:=false;

  startTime := GetTickCount;

  //Befehlesfolge deren Zeitdauer bestimmt werden soll
    Present:= Now;
  SysUtils.DecodeDate(Present, Year, Month, Day);
  Label1.Caption := 'Der heutige Tag ist der ' + Dezinroem(IntToStr(Day)) + ' des '+Dezinroem(inttoStr(Month)) +'. Monates '
     + ' des Jahres ' + DezinRoem(IntToStr(Year));

  SysUtils.DecodeTime(Present, Hour, Min, Sec, MSec);
  Label2.Caption := DezInRoem(inttostr(Hour))+ ' Stunden, '+DezInRoem(inttostr(Min))+' Minuten und '
     +DezinRoem(inttostr(Sec))+' Sekunden und '+DezinRoem(inttostr(MSec)) +' Milisekunden';
  Label4.Caption:=DezInRoem(inttostr(Hour));
  Label5.caption:=DezInRoem(inttostr(Min));
  Label6.caption:=DezInRoem(inttostr(Sec));
  Label7.caption:=DezInRoem(inttostr(mSec));

  ShowMessage('Die Routine benötigte etwa ' + DezInRoem(IntToStr(GetTickCount - startTime)) + 'ms');

  timer2.Enabled:=true;
end;
Ich habe sie jedoch nur ohne Umwandlung in roem. Zahlen gemessen, da so wie oben geschrieben kein Wert ausgegeben wird.
Also ist alles so wie bislang geschrieben?
Habe ich nun den richtigen Ansatz für die Berechnung der Zeitdifferenz? Wie gibt man eigentlich eine Null in roem. Zahlen aus?
Das Problem übersteigt wohl doch meine Möglichkeiten.

nahpets 18. Jan 2017 21:21

AW: Programm Wurzelberechnung nach Heron
 
Bei den römischen Zahlen gibt es keine 0, kann von daher auch nicht ausgegeben werden ;-)

Was ich mit der Intervallberechnung bezwecken möchte, mal ein Beispiel:

Das Programm wird um 21:36:45,567 gestartet und soll zu jeder vollen Sekunde ein Timerereignis ausführen.

Wir benötigen hier also die Anzahl der Millisekunden zwischen

21:37:00,000
und
21:36:45,567

Das wäre das Timerintervall, das gesetzt werden müsste.

Klar, bei so einer Aufgabe, wie der Ausgabe der Uhrzeit, ist die Laufzeit so kurz, dass eine Neuberechnung absurd erscheint.
Wenn Du Deine Uhr aber mal über einen längeren Zeitraum laufen lässt, wirst Du bemerken, dass die Zahl der Millisekunden langsam, aber kontinuierlich, ansteigt.
Bei meinem Rechner zwischen 2 und 3 Millisekunden pro Minute, das sind am Tag irgendwas zwischen 2880 und 4320 Millisekunden.

Auf's Jahr gerechnet werden daraus zwischen 1051200 und 1576800 Millisekunden, gibt also sowas um die 20 Sekunden. Hier wäre es schön, wenn die Uhr diesen Fehler selbst korrigieren könnte. Dazu muss halt ab und an das Timerintervall etwas kürzer als 1000 Millisekunden sein. So, wie es auf meinem Rechner aussieht, zwei bis dreimal pro Minute.

Hier mal ein paar Fragmente aus 'ner von TTimer abgeleiteten Komponente von mir:
Delphi-Quellcode:
const
  iOneSecond     : Integer =    1000; // eine Sekunde in Millisekunden
  iFiveSeconds   : Integer =    5000; // fünf Sekunden in Millisekunden
  iFifteenSeconds : Integer =   15000; // fünfzehn Sekunden in Millisekunden
  iOneMinute     : Integer =   60000; // eine Minute in Millisekunden
  iFiveMinutes   : Integer =  300000; // Fünf Minuten in Millisekunden
  iFifteenMinutes : Integer =  900000; // Fünfzehn Minuten in Millisekunden
  iOneHour       : Integer = 3600000; // Eine Stunde in Millisekunden
  iOneDay        : Integer = 86400000; // Ein Tag in Millisekunden

function TSpecialTimer.CalcTimerInterval(iTimerInterval : Integer) : Integer;
Var
          dNow : Double;
begin
  // Interval setzen
  // Tagesdatum und Uhrzeit holen
  dNow := Now;
  // Den Tagesanteil holen (= Nachkommastellen).
  dNow := dNow - Trunc(dNow);
  // Rest bis Mitternacht holen.
  dNow := 1 - dNow;
  // Nachkommastellen mal Millisekunden pro Tag
  Result := Trunc(dNow * iOneDay);
  // wir benötigen den Rest bis zum angegeben Interval, damit der Timer
  // zur nächsten Minute, Stunde, 0 Uhr ... aktive wird.
  Result := (Result mod Max(iTimerInterval,1));
end;
Der Aufruf könnte dann z. B. so erfolgen:
Delphi-Quellcode:
// Damit der Timer zur nächsten vollen Sekunde ausgelöst wird:
Timer1.Interval := CalcTimerInterval(iOneSecond);
// Zur nächsten vollen Viertelstunde, um den Glockenschlag für die Viertelstunde auszulösen:
Timer2.Interval := CalcTimerInterval(iFifteenMinutes);
// Oder um Mitternacht, z. B. für den Datumswechsel:
Timer3.Interval := CalcTimerInterval(iOneDay);

BrightAngel 18. Jan 2017 21:55

AW: Programm Wurzelberechnung nach Heron
 
Zitat:

Zitat von EdAdvokat (Beitrag 1358971)
Ich suche nach Programmideen, nachdem ich hier im Forum bereits eine Warenberechnung (Programm Waren) und den Verkauf von Kinokarten (Programm Kinokarten) vorgestellt habe. Bei der Realisierung dieser Programme konnte ich eine Reihe von Anregungen umsetzen und habe dabei viel dazugelernt.
Ich will keineswegs auf der Stelle treten. [...]
Ich werde also weitergrübeln und die Foren durchstreifen. Wenn jemand eine Idee haben solle, wäre ich dafür dankbar.:!:

Kennst du Sudoku? Das gibt es mittlerweile in verschiedenen Geschmacksrichtungen und sogar schon in 3D :-D
Ich kenne jetzt nicht so genau deine Aufgabenpräferenz, aber vielleicht reizt dich das ja?
Besonders das Erstellen und Lösen solcher Sudokus dem Computer beizubringen bringt dich vielleicht weiter?

Brighty

EdAdvokat 19. Jan 2017 09:54

AW: Programm Wurzelberechnung nach Heron
 
nun habe ich auch über einen längeren Zeitraum die Zeitdauer der Ausführung des Programmteils gemessen und stets den Wert 0 ms erhalten.
Nehmen wir mal Dein Beispiel mit einer Zeitdauer von angenommen 15 ms für die Programmausführung. Dann müsste also das Intervall auf 985 ms gesetzt werden, damit dann genau zur neuen sec. der neue Ablauf der Bestimmung der roem. Zahlen auf dem Turm neu beginnen kann? Sehe ich das so richtig?:?:
Ich habe mit 2 Methoden die Messung vorgenommen und immer nur 0 ms erhalten. Somit kann ich also kein Intervall setzen oder? Anbei das Beispiel für die Messung mit einer der beiden Methoden:

Delphi-Quellcode:
procedure TForm1.Timer2Timer(Sender: TObject);   //Messung Intervall
var
  freq: Int64;
  startTime: Int64;
  endTime: Int64;
  Present: TDateTime;
  Year, Month, Day, Hour, Min, Sec, MSec: Word;
  Zeit : String;
 begin
 timer2.Enabled:=false;

  QueryPerformanceFrequency(freq);
  QueryPerformanceCounter(startTime);


  Present:= Now;
  SysUtils.DecodeDate(Present, Year, Month, Day);
  Label1.Caption := 'Der heutige Tag ist der ' + Dezinroem(IntToStr(Day)) + ' des '+Dezinroem(inttoStr(Month)) +'. Monates '
     + ' des Jahres ' + DezinRoem(IntToStr(Year));

  SysUtils.DecodeTime(Present, Hour, Min, Sec, MSec);
  Label2.Caption := DezInRoem(inttostr(Hour))+ ' Stunden, '+DezInRoem(inttostr(Min))+' Minuten und '
     +DezinRoem(inttostr(Sec))+' Sekunden und '+DezinRoem(inttostr(MSec)) +' Milisekunden';
  Label4.Caption:=DezInRoem(inttostr(Hour));
  Label5.caption:=DezInRoem(inttostr(Min));
  Label6.caption:=DezInRoem(inttostr(Sec));
  Label7.caption:=DezInRoem(inttostr(mSec));

  Zeit:=timeToStr(Time);
    Panel1.Caption:=Zeit;
   // Panel1.Caption:=TimeToStr(Time);
    StatusBar1.Panels[0].Text:=TimeToStr(Time);
    StatusBar1.Panels[1].Text:=FormatDateTime('"Heute ist "dddd," der "d.mmmm yyyy"',Date);
    DecodeTime(Time, Hour, Min, Sec, mSec);
    Trackbar1.Position:=Sec;


 QueryPerformanceCounter(endTime);
  timer2.Enabled:=true;
  ShowMessage('Die Routine benötigte etwa ' + IntToStr((endTime - startTime) * 1000 div freq) + ' ms');

end;

nahpets 19. Jan 2017 11:56

AW: Programm Wurzelberechnung nach Heron
 
Du hast da wohl einen schnelleren Rechner als ich.

Zu Deinem :?:: Ja, Du gehst recht in der Annahme.

Mess' bitte noch einmal, aber mit anderen Bedingungen.

Setze die Priorität der Uhr (im Taskmanager) mal auf den niedrigstmöglichen Wert.
Starte einen anderen Prozess (oder mehrere), von denen Du weißt, das richtig Systemlast erzeugt wird, setze deren Priorität eventuell auf Hoch, bei Echtzeit kann es sein, dass Du Windows nicht mehr so recht bedienen kannst. Prüfe dann, ob die Uhr weiterhin genau geht.

Deine obige Berechnung ist genau das, was ich meine. Bei meinem Rechner müsste zwei- bis dreimal pro Minute das Intervall auf 999 gesetzt werden.

Unabhängig von den Messerergebnissen:
Wenn Du das Intervall immer neu berechnest, kommt bei der Berechnung halt (fast) immer 1000 heraus, dann wird eben das Intervall (fast) immer auf 1000 gesetzt, macht nix. Sollte aber mal (irgendwann im Laufe des Jahres) aus welchem Grund auch immer, die Uhr etwas nachgehen, dann korrigiert sie sich eben halt dann bei der Berechnung des Intervalls zur nächsten Sekunde.
Die Schaltsekunde von vor Kurzem hätte sie so auch automatisch korrigieren können. Auch eine beliebige Umstellung der Systemuhr (um Sekundenbruchteile) würde sie so automatisch korrigieren.

Sagen wir mal so: Wenn Du hier in Deinen Quelltext noch meine Routine von oben einbaust
Delphi-Quellcode:
  QueryPerformanceCounter(endTime);
  timer2.Interval := CalcTimerInterval(iOneSecond);
  timer2.Enabled:=true;
  ShowMessage('Die Routine benötigte etwa ' + IntToStr((endTime - startTime) * 1000 div freq) + ' ms');
bin ich schon zufrieden.

Um zu prüfen, ob dies auch wirklich geht, setze die Aktuallisierungszeit mal auf die volle Minute und schau dann, ob die Zeitangabe immer HH:MM:00,000 (+/- 1 MS) ist.

Als Chromleiste:

Baue, wenn Du mit dem bisherigen klargekommen bist und das zu Deiner Zufriedenheit funktioniert, mal einen Nachfahren von TTimer, der, beim Setzen von Enabled := True, automatisch das Intervall auf die nötige Anzahl von Millisekunden bis zur nächsten vollen Sekunde setzt.

Ein von mir gebauter TTimer-Nachfahre hat u. a. folgende Attribute:
Delphi-Quellcode:
    // Zu jeder vollen Sekunde (HH:MM:00,000, HH:MM:01,000, HH:MM:02,000, ...)
    property   OneSecond     : Boolean     read GetOneSecond     Write SetOneSecond     default False;
    // Alle fünf Sekunden (HH:MM:00,000, HH:MM:05,000, HH:MM:10,000, ...)
    property   FiveSeconds   : Boolean     read GetFiveSeconds   Write SetFiveSeconds   default False;
    // Alle fünfzehn Sekunden (HH:MM:00,000, HH:MM:15,000, HH:MM:30,000, ...)
    property   FifteenSeconds : Boolean     read GetFifteenSeconds Write SetFifteenSeconds default False;
    // Jede volle Minute (HH:01:00,000, HH:02:00,00, HH:03:00,000 ...)
    property   OneMinute     : Boolean     read GetOneMinute     Write SetOneMinute     default False;
    // Jede vollen fünf Minuten (HH:00:00,000, HH:05:00,000, HH:10:00,000, ...)
    property   FiveMinutes   : Boolean     read GetFiveMinutes   Write SetFiveMinutes   default False;
    // Jede vollen fünfzehn Minuten (HH:00:00,000, HH:15:00,000, HH:30:00,000, ...)
    property   FifteenMinutes : Boolean     read GetFifteenMinutes Write SetFifteenMinutes default False;
    // Jede volle Stunde (01:00:00,000, 02:00:00,000, 03:00:00,000 ...)
    property   OneHour       : Boolean     read GetOneHour       Write SetOneHour       default False;
    // Um Mitternacht (00:00:00,000)
    property   Midnight      : Boolean     read GetMidnight      Write SetMidnight      default False;

    property   Enabled       : Boolean     read GetEnabled       Write SetEnabled       default False;
    property   Interval      : Cardinal    read GetInterval      Write SetInterval      default 1000;
    property   OnTimer       : TNotifyEvent read fOnTimer         Write SetOnTimer;
Sie dienen dazu, wenn einer der boolschen Werte gesetzt ist, wird das Timerereignis zu exakt diesem Zeitpunkt ausgelöst. Es kann (neben Enabled) immer nur einer der Werte auf True stehen. Die Änderung eines der Werte setzt die anderen automatisch auf False. Das Setzen von Enabled auf True berechnet automatisch für das Intervall die benötigte Anzahl von Millisekunden bis zum Eintreten dieses Zeitpunktes, ist keiner der boolschen Werte gesetzt, so wird das Intervall unverändert belassen, es bleibt also die Funktionälität des Vorfahrens TTimer erhalten.

EdAdvokat 19. Jan 2017 14:36

AW: Programm Wurzelberechnung nach Heron
 
Liste der Anhänge anzeigen (Anzahl: 1)
ich hab Deiner Empfehlung folgend beiliegendes geschrieben. Bin aber selbst davon nicht so richtig überzeugt, zumal sich der constructor create nicht aufrufen läßt und auch sonst ist das wohl so la la...
Ist es zuminstest etwa in die richtige Richtung? Was sollte ich also mit der abgeleiteten class tun? (hoffentlich keine zu blöde Frage)

Fritzew 19. Jan 2017 16:16

AW: Programm Wurzelberechnung nach Heron
 
Ok dann gebe ich auch noch meinen Senf dazu.......

Ich schreibe jetzt hier nur mal was mir beim überfliegen so aufgefallen ist ;-)
  • Du hast leere try Finally Blöcke. Wozu sollen die gut sein?
  • Gewöhne Dir an Rückgaben von Funktionen auch auszuwerten, macht Deinen Code sehr viel robuster. zb. QueryPerformanceFrequency etc
  • EventRoutinen immer so kurz wie möglich halten. Bsp:

Delphi-Quellcode:
procedure TForm1.Timer2Timer(Sender: TObject); // Messung Intervall
begin
   Timer2.Enabled := false;
   UpdateVisualData(now);
   Timer2.Interval := CalcTimerInterval(iOneSecond);
   Timer2.Enabled := true;
end;

procedure TForm1.UpdateVisualData(const Present: TDateTime); // Update Form
var
   Present: TDateTime;
   Year, Month, Day, Hour, Min, Sec, MSec: Word;
   Zeit: string;
begin
   SysUtils.DecodeDate(Present, Year, Month, Day);
   Label1.Caption := 'Der heutige Tag ist der ' + DezInRoem(IntToStr(Day)) + ' des ' + DezInRoem(IntToStr(Month)) + '. Monates ' +
    ' des Jahres ' + DezInRoem(IntToStr(Year));

   SysUtils.DecodeTime(Present, Hour, Min, Sec, MSec);
   Label2.Caption := DezInRoem(IntToStr(Hour)) + ' Stunden, ' + DezInRoem(IntToStr(Min)) + ' Minuten und ' + DezInRoem(IntToStr(Sec)) +
    ' Sekunden und ' + DezInRoem(IntToStr(MSec)) + ' Milisekunden';
   Label4.Caption := DezInRoem(IntToStr(Hour));
   Label5.Caption := DezInRoem(IntToStr(Min));
   Label6.Caption := DezInRoem(IntToStr(Sec));
   Label7.Caption := DezInRoem(IntToStr(MSec));

   Zeit := timeToStr(Time);
   Panel1.Caption := Zeit;

   StatusBar1.Panels[0].Text := timeToStr(Time);
   StatusBar1.Panels[1].Text := FormatDateTime('"Heute ist "dddd," der "d.mmmm yyyy"', Date);
   DecodeTime(Time, Hour, Min, Sec, MSec);
   TrackBar1.Position := Sec;
end;
So kannst Du jederzeit die Form mit UpdateVisual(now) updaten;
Wie z.B in deinem Button2Click

Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
var
   freq: Int64;
   startTime: Int64;
   endTime: Int64;
begin
   Timer2.Enabled := false;
   if QueryPerformanceFrequency(freq) and
   QueryPerformanceCounter(startTime) then
  begin
   // Befehlesfolge deren Zeitdauer bestimmt werden soll
   UpdateVisualData(now);
   QueryPerformanceCounter(endTime);
   ShowMessage('Die Routine benötigte etwa ' + IntToStr((endTime - startTime) * 1000 div freq) + ' ms');
  end
  else
  begin
    // Hier sollte eigentlich untersucht werden was nicht gegangen ist getLastError oder so
     ShowMessage('OOPS');
  end;
 Timer2.Enabled := true;
 
end;
Ach ja schau Dir auch noch die System.DateUtils; an. Da sind einige interessante Routinen rund um Time/Date drin

nahpets 19. Jan 2017 16:48

AW: Programm Wurzelberechnung nach Heron
 
Hab' mir den Quelltext mal angeschaut.

Wenn man einen Timer auf Enabled setzt, so wird der in Intervall befindliche Zeitraum genutzt. Wird das Intervall erst nach Enabled := True; gesetzt, so hat es keine Auswirkung mehr, bzw. erst nach dem nächsten Enabled := False; ... Enabled := True;

Hab' einfach mal ein bisserl überarbeitet:
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, ExtCtrls, Math,
{$IFDEF VER150} // Delphi 7
  StdCtrls, Buttons, jpeg;
{$ELSE}
  Vcl.StdCtrls, Vcl.Buttons, Vcl.Imaging.jpeg;
{$ENDIF}

type
  TTimerNW = class(TTimer)
   private
    fOneSecond : Boolean;
    fMidnight : Boolean;
    function CalcTimerInterval(iTimerInterval : Integer) : Integer;
    function GetEnabled:boolean;
    function GetInterval: cardinal;
    procedure init;
    procedure SetEnabled(e: boolean);
    procedure SetInterval(i: cardinal);
    procedure SetMidNight(AValue : Boolean);
    procedure SetOneSecond(AValue : Boolean);
   public
     constructor Create(AOwner: TComponent); override;
     destructor Destroy; override;
   published
    property Enabled  : Boolean read GetEnabled write SetEnabled default False;
    property Interval : Cardinal read GetInterval write SetInterval default 1000;
    property OneSecond : Boolean read fOneSecond write SetOneSecond;
    property MidNight : Boolean read fMidNight write SetMidNight;
  end;

type
  TForm1 = class(TForm)
    BitBtnClose: TBitBtn;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Image1: TImage;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    Panel1: TPanel;
    StatusBar1: TStatusBar;
    TrackBar1: TTrackBar;
    procedure BitBtnCloseClick(Sender: TObject);
    procedure Sekundenanzeige(Sender: TObject);
    procedure Datumsanzeige(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen }
    fTimer  : TTimerNW;
    ftmDatum : TTimerNW;
    procedure Ausgabe;
  public
    { Public-Deklarationen }
  end;

const
  iOneSecond     : Integer = 1000;    // eine Sekunde in Millisekunden
  iFiveSeconds   : Integer = 5000;    // fünf Sekunden in Millisekunden
  iFifteenSeconds : Integer = 15000;   // fünfzehn Sekunden in Millisekunden
  iOneMinute     : Integer = 60000;   // eine Minute in Millisekunden
  iFiveMinutes   : Integer = 300000;  // Fünf Minuten in Millisekunden
  iFifteenMinutes : Integer = 900000;  // Fünfzehn Minuten in Millisekunden
  iOneHour       : Integer = 3600000; // Eine Stunde in Millisekunden
  iOneDay        : Integer = 86400000; // Ein Tag in Millisekunden

  csHeute  = 'Der heutige Tag ist der %s des %s. Monates des Jahres %s.';
  csUhrzeit = '%s Stunden, %s Minuten, %s Sekunden und %s Millisekunden';

var
  Form1: TForm1;

implementation

{$R *.dfm}

constructor TTimerNW.create;
begin
  inherited Create(AOwner);
  fOneSecond       := False;
  fMidnight        := False;
  init;
end;

destructor TTimerNW.Destroy;
begin
  inherited Destroy;
end;

procedure TTimerNW.init;
begin
  inherited Interval := 1000;
  inherited Enabled := True;
end;

procedure TTimerNw.SetEnabled(e: Boolean);
begin
       if fOneSecond then Interval := CalcTimerInterval(iOneSecond)
  else if fMidNight then Interval := CalcTimerInterval(iOneDay);
  inherited Enabled := e;
end;

procedure TTimerNW.SetInterval(i: Cardinal);
begin
  if i = 0 then i := 1000;
  inherited Interval := i;
end;

function TTimerNW.GetInterval;
begin
  inherited;
  Result := inherited Interval;
end;

function TTimerNW.GetEnabled;
begin
  Result := inherited Enabled;
end;

function TTimerNW.CalcTimerInterval(iTimerInterval : Integer) : Integer;
Var
  dNow : Double;
begin
  // Interval setzen
  // Tagesdatum und Uhrzeit holen
  dNow := Now;
  // Den Tagesanteil holen (= Nachkommastellen).
  dNow := dNow - Trunc(dNow);
  // Rest bis Mitternacht holen.
  dNow := 1 - dNow;
  // Nachkommastellen mal Millisekunden pro Tag
  Result := Trunc(dNow * iOneDay);
  // wir benötigen den Rest bis zum angegeben Interval, damit der Timer
  // zur nächsten Minute, Stunde, 0 Uhr ... aktive wird.
  Result := (Result mod Max(iTimerInterval,1));
end;

procedure TTimerNW.SetOneSecond(AValue : Boolean);
begin
  fOneSecond := AValue;
  if AValue then begin
    fMidNight := false;
    Interval := CalcTimerInterval(iOneSecond);
  end;
end;

procedure TTimerNW.SetMidNight(AValue : Boolean);
begin
  fMidNight := AValue;
  if AValue then begin
    fOneSecond := false;
    Interval  := CalcTimerInterval(iOneDay);
  end;
end;

function DezInRoem(n:Integer):string;
  function teil(const groessenordnung1,groessenordnung2:integer;
                var rest:integer;
                const zeichen1,zeichen2:char):string;
    begin
      result:='';
      while rest>=groessenordnung1 do
      begin
        dec(rest,groessenordnung1); //rest:=rest-groessenordnung;
        result:=result+zeichen1; //z.B. +'M'
      end;
      if rest>=groessenordnung2 then
      begin
        dec(rest,groessenordnung2);
        result:=result+zeichen2+zeichen1; //z.B. +'CM'
      End;
    end;
begin
  result := ''; //in Delphi automatisch
  result := result + teil(1000,900,n,'M','C');
  result := result + teil( 500,400,n,'D','C');
  result := result + teil( 100, 90,n,'C','X');
  result := result + teil(  50, 40,n,'L','X');
  result := result + teil(  10, 9,n,'X','I');
  result := result + teil(   5, 4,n,'V','I');
  result := result + teil(   1, 1,n,'I','I');
end;

procedure TForm1.BitBtnCloseClick(Sender: TObject);
begin
  close;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  startTime: Cardinal;
begin
  startTime := GetTickCount;
  //Befehlesfolge deren Zeitdauer bestimmt werden soll
  Ausgabe;
  // ShowMessage('Die Routine benötigte etwa ' + (IntToStr(GetTickCount - startTime)) + ' ms');
  fTimer.Enabled := true;
  // showMessage(floattostr(timer2.Interval));
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  freq: Int64;
  startTime: Int64;
  endTime: Int64;
begin
  fTimer.Enabled := false;
  QueryPerformanceFrequency(freq);
  QueryPerformanceCounter(startTime);
  //Befehlesfolge deren Zeitdauer bestimmt werden soll
  Ausgabe;
  QueryPerformanceCounter(endTime);
  fTimer.Enabled := true;
//  ShowMessage('Die Routine benötigte etwa ' + IntToStr((endTime - startTime) * 1000 div freq) + ' ms');
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  // Damit der Timer zur nächsten vollen Sekunde ausgelöst wird:
  fTimer.Interval := fTimer.CalcTimerInterval(iOneSecond);
  //showMessage(inttostr(CalcTimerInterval(iOneSecond)));
  // showMessage(inttostr(Timer2.Interval));
  // Zur nächsten vollen Viertelstunde, um den Glockenschlag für die Viertelstunde auszulösen:
  fTimer.Interval := fTimer.CalcTimerInterval(iFifteenMinutes);
  // Oder um Mitternacht, z. B. für den Datumswechsel:
  fTimer.Interval := fTimer.CalcTimerInterval(iOneDay);
end;

procedure TForm1.Sekundenanzeige(Sender: TObject);   //Messung Intervall
var
  freq    : Int64;
  startTime: Int64;
  endTime : Int64;
  Present : TDateTime;
  Hour, Min, Sec, MSec: Word;
begin
  fTimer.Enabled := false;
  QueryPerformanceFrequency(freq);
  QueryPerformanceCounter(startTime);
  Ausgabe;
  Present := Now;
  Panel1.Caption := timeToStr(Present);
  StatusBar1.Panels[0].Text := TimeToStr(Present);
  SysUtils.DecodeTime(Present, Hour, Min, Sec, MSec);
  Trackbar1.Position       := Sec;
  QueryPerformanceCounter(endTime);
  fTimer.Enabled := true;
  // ShowMessage('Die Routine benötigte etwa ' + IntToStr((endTime - startTime) * 1000 div freq) + ' ms');
end;

procedure TForm1.Datumsanzeige(Sender: TObject);
var
  Present : TDateTime;
begin
  ftmdatum.Enabled := false;
  Present         := Now;
  Panel1.Caption  := timeToStr(Present);
  StatusBar1.Panels[1].Text := FormatDateTime('"Heute ist "dddd," der "d.mmmm yyyy"',Present);
  ftmDatum.Enabled := true;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  fTimer           := TTimerNW.Create(Self);
  fTimer.OnTimer   := Sekundenanzeige;
  fTimer.OneSecond := True;
  Sekundenanzeige(Sender);
  ftmDatum         := TTimerNW.Create(Self);
  ftmDatum.MidNight := True;
  Datumsanzeige(Sender);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  ftmDatum.Free;
  fTimer.Free;
end;

procedure TForm1.Ausgabe;
var
  Present: TDateTime;
  Year, Month, Day, Hour, Min, Sec, MSec: Word;
begin
  Present := Now;
  SysUtils.DecodeDate(Present, Year, Month, Day);
  SysUtils.DecodeTime(Present, Hour, Min, Sec, MSec);
  Label1.Caption := Format(csHeute,[Dezinroem(Day), Dezinroem(Month), DezinRoem(Year)]);
  Label2.Caption := Format(csUhrzeit,[DezInRoem(Hour),DezInRoem(Min), DezinRoem(Sec), DezinRoem(MSec)]);
  Label4.Caption := DezInRoem(Hour);
  Label5.Caption := DezInRoem(Min);
  Label6.Caption := DezInRoem(Sec);
  Label7.Caption := DezInRoem(mSec);
end;

end.
Bei der Uhr vom Düsseldorfer Fernmeldeturm meinte ich übrigens dieses hier: https://commons.wikimedia.org/wiki/F...rm_uhrzeit.jpg bzw. dashier: http://www.keifzicke.de/Dssd_Rheinturm.html oder auch jenes: http://www.wiegels.net/tuerme/hoch/rz101.jpg

EdAdvokat 19. Jan 2017 17:03

AW: Programm Wurzelberechnung nach Heron
 
Danke erst einmal. Das muss ich mir ganz in Ruhe einziehen. Es ist doch noch eine ganze Menge zu tun....:?


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