Division durch 0

Hier kann alles mögliche diskutiert werden. Themen zu Purebasic sind hier erwünscht.
Flames und Spam kommen ungefragt in den Mülleimer.
Benutzeravatar
PureBaser
Beiträge: 180
Registriert: 08.09.2004 21:20
Wohnort: Berlin
Kontaktdaten:

Division durch 0

Beitrag von PureBaser »

Wie kann ein Computer so schnell sein, dass das bei alten Programmen (insbesondere Dos-Anwendungen) geschieht? Wird diese Gefahr eines Tages auch PB-Programme bzw. heutige Programme anzutreffen sein, wenn es die Quad-Systeme à 10 Ghz (fiktiv) geben wird?
PB4 & WinXP_SP2
Benutzeravatar
Laurin
Beiträge: 1639
Registriert: 23.09.2004 18:04
Wohnort: /dev/eth0

Beitrag von Laurin »

Das Problem ist, dass früher häufig eine kleine Schleife am Anfang des Programms ausgeführt wurde, um ungefähr die Rechnergeschwindigkeit zu ermitteln. Diese Schleifen werden heutzutage so schnell durchlaufen, dass das Programm für die Durchführungszeit 0 Sekunden o. ä. herausbekommt. Und wenn man jetzt mit 0 rechnet, weiß man ja, was dabei rauskommt.

Aber für sowas gibt extra Verlangsamungsprogramme, z.B. SlowDown. Emulatoren gibt es auch zur Genüge, z.B. DosBox. Damit treten solche Probleme in der Regel nicht mehr auf.
Now these points of data make a beautiful line.
And we're out of beta. We're releasing on time.
Benutzeravatar
Deeem2031
Beiträge: 1232
Registriert: 29.08.2004 00:16
Wohnort: Vorm Computer
Kontaktdaten:

Beitrag von Deeem2031 »

Der Fehler ensteht durch einen Speedtest der ungefähr so aussieht:

Code: Alles auswählen

#r = 1000
time = ElapsedMilliseconds()
For i = 1 To #r
  a+1
Next
time = ElapsedMilliseconds() - time
MessageRequester("","a+1 braucht "+Str(#r/time)+"ms")
Die allten Programme die du meinst haben nämlich von einer best. Aktion die Zeit gemessen und später diese Aktion bei 'nem Delay() so oft aufgerufen wie es gebraucht wird. Problem dabei ist nur das selbe wie bei dem Test oben, theoretisch sollte es funktionieren, tuts aber nicht weil die Zeit die gebraucht wird zu klein ist. Da das Delay von PB aber nicht so aufgebaut ist, darfst du unbesorgt weiter proggen.
Bild
[url=irc://irc.freenode.org/##purebasic.de]irc://irc.freenode.org/##purebasic.de[/url]
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

nachdem ich alle postings gelesen hab, versteh ich worum es geht.

dein posting hat mich aber zuerst verwirrt, purebaser, weil ich zuerst nicht wusste, was du willst: titel "division durch 0", und redest über geschwindigkeit.

klar, bei so nem algorythmus zum geschwindigkeit ermitteln wie von Laurin und Deeem beschrieben kann so ein fehler geschwindigkeitsbedingt sein.

aber in allen anderen fällen hat eine div/0 nichts mit dem tempo zu tun, sondern ob du deine algorythmen so absicherst, das er nicht auftreten kann.
im grunde also bei jeder division, die du einbaust kurz überlegen, ob der divisor mal null sein kann aus irgendwelchen gründen. das kann einem so in fleisch und blut übergehen, dass man später garnicht mehr drüber nachdenkt, es einem aber automatisch einfällt, hoppla, hier muss ich die null vorher abfragen.

bei timerprogrammierungen wie das hier im forum oft besprochen wird kann so ein fehler nie auftreten. und da bei topics darüber oft von synchronisierung und so gesprochen wird, dass immer zur sprache kommt, wie man timer baut damit das programm gleich schnell auf 500MHz und auf 3.3GHz läuft, ist das sicher, dass läuft auch fehlerfrei gleichschnell auf 1000TeraHz.

Have a nice day, folks
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Leonhard
Beiträge: 602
Registriert: 01.03.2006 21:25

Beitrag von Leonhard »

Den Fehler kann man glücklicherweise umgehen: Man ändert den Wert von 8087CW. Den Wert sollte man beim beenden des Programmes wieder auf den Standart-Wert setzen.

Hirmit ermittelt man den aktuellen Wert:

Code: Alles auswählen

Procedure.w GetDefault8087CW() ;Default8087CW
  !PUSH 0
  !FSTCW [Esp]
  !POP Eax
  ProcedureReturn 
EndProcedure
Und hiermit Setzt man den Wert:

Code: Alles auswählen

Procedure Set8087CW(ControlWord.w) ;Set8087CW
  !PUSH Eax
  !FLDCW [Esp]
  !POP Eax
EndProcedure
Und jetzt nocht, wie der Wert gesetzt werden soll:

Code: Alles auswählen

#MCW_EM = $8001F    ; Setze Neuen FPU-Wert in eine Konstance
; In Delphi so erstellt: #MCW_EM = DWORD($133f)
Erklärung:
Mit der setzung auf #MCW_EM wird die Division durch #Null (0) "ausgeschaltet".
Benutzeravatar
PureBaser
Beiträge: 180
Registriert: 08.09.2004 21:20
Wohnort: Berlin
Kontaktdaten:

Beitrag von PureBaser »

Danke, war sehr hilfsreich!
PB4 & WinXP_SP2
Antworten