AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Probleme mit Bereichsüberprüfung

Ein Thema von heiopei · begonnen am 14. Okt 2007 · letzter Beitrag vom 19. Okt 2007
Antwort Antwort
heiopei
(Gast)

n/a Beiträge
 
#1

Probleme mit Bereichsüberprüfung

  Alt 14. Okt 2007, 11:08
Hallo,
ich bin gerade dabei, einen funktionenplotter für meine facharbeit zu entwickeln (Die Ausgabe ist bereits komplett fertig). Dabei ist die Anzeige frei skalierbar, d.h. jeder Funktionswert wird durch eine Skalierungskonstante dividiert, wenn die Funktion angezeigt werden soll.
(Bsp. Skalierungskonstante = 0,01 -> Ein Pixel = 0,01 ; Wert vorher: 10,12 => Wert nachher: 1012 => dem Wert wird der Integerwert 1012 zugewiesen)

So, jetzt hab ich aber das Problem, dass ich dauernd mit Double-Werten rechne und sie erst am ende der Werte-Transformation in Integer-Werte umrechne, um sie dann als Pixelwerte behandeln zu können. Allerdings bekomme ich z.b. für die funktion f(x)=x² irgendwann so große werte, dass ich bei der Zuweisung NeuerWert = Round(AlterWerte / Skalierung) einen overflow erhalte - klar. Jetzt wollte ich diesen Overflow abfangen:

NeuerWert := Round(EnsureRange(AlterWert / Skalierung, Low(Integer), High(Integer));

(EnsureRange ist eine Funktion aus der Unit Math, siehe OH)

Allerdings erhalte ich ab einem bestimmten Punkt einen Bluescreen mit der Meldung, dass ein Fehler in der win32.dll (oder exe, bin mir grad nicht sicher) aufgetreten ist.

Wie kann ich diesen Fehler umgehen?

mfg,
heiopei

Edit:
hHab jetzt nochmal die etwas genauere Beschreibung des Bluescreens
PAGE_FAULT_IN_NONPAGED_AREA

win32k.sys - Address BF87920A base at BF800000, DateStamp 41107f7a

tech. Info: STOP: 0x00000050 (0xEE3F2060, 0x00000001, 0xBF87920A, 0x000000000)
  Mit Zitat antworten Zitat
heiopei
(Gast)

n/a Beiträge
 
#2

Re: Probleme mit Bereichsüberprüfung

  Alt 15. Okt 2007, 15:44
hallo nochmal,
so... ich hab mich jetzt noch ein bisschen gespielt und bemerkt, dass Round als Ergebnistyp Int64 liefert! Daher hab ich jetzt folgende Typcasts durchgeführt - und es ging:

var
tmp: Int64;
begin
tmp := Round(EnsureRange(AlterWert / Skalierung, Low(Integer), High(Integer));
NeuerWert := Integer(tmp);
...

Allerdings erhalte ich für sehr große x-Werte bei f(x)=x² komische Werte - z.T. null oder negativ.
Liegt vermutlich an Overflows - oder?.

Wie kann ich das Problem am besten lösen, so dass ich nur "NeueWerte" bis High(Integer) erhalte und alle Werte, die darüber hinaus gehen = High(Integer) setzt werden?????
(am besten, ohne Bluescreen )

mfg,
heiopei
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#3

Re: Probleme mit Bereichsüberprüfung

  Alt 15. Okt 2007, 18:47
Na einfach abfangen:
Delphi-Quellcode:
var
tmp: Int64;
begin
  tmp := Round(EnsureRange(AlterWert / Skalierung, Low(Integer), MaxInt);

  NeuerWert := Min(tmp, MaxInt);
end;
  Mit Zitat antworten Zitat
heiopei
(Gast)

n/a Beiträge
 
#4

Re: Probleme mit Bereichsüberprüfung

  Alt 16. Okt 2007, 13:19
hallo Muetze1,
ich habs jetzt so wie du gemacht, bekomme aber wieder einen Bluescreen!!!! Arg....

Wo meint ihr, entsteht der Overflow, wie kann ich ihn abfangen?

PS: Sorry, aber ich komme einfach nicht mehr weiter, bzw. es fällt mir nichts mehr ein, was mich weiterbringt

danke für hilfe schon im voraus,
heiopei


PS2: momentan mache ich die umformung wie folgt:

var
tmp: Double;
tmp2: Int64;
res: Integer;
begin
tmp := AlterWert / Skalierung;
tmp2 := Round(tmp);
res := Integer(tmp2);
end;

Die Umformungen gehen natürlich auch einfacher, sollen die sache aber besser demonstrieren; dieser code liefert mir keinen bluescreen, aber für x^2 irgendwann negative werte...
  Mit Zitat antworten Zitat
heiopei
(Gast)

n/a Beiträge
 
#5

Re: Probleme mit Bereichsüberprüfung

  Alt 18. Okt 2007, 14:47
hallo,

durch ewiges testen hab ich jetzt rausgefunden, dass der Fehler nicht an meiner umwandlung, sondern an dem Aufruf von Canvas.Polyline zum zeichnen der Funktion liegt.

Sobald ich die Zeile auskommentiere in der ich das Array mit den in Integerwerte umgerechneten Punkten an Polyline übergebe, erhalte ich für große skalierungen keinen Bluescreen mehr (aber natürlich auch keine Grafik mehr ).
Daraus folgere ich, dass ich mein Array korrekt erstellt habe. Kann es sein, dass es da irgend einen Fehler beim Aufruf der WIN-API-Funktion mit extremen Koordinaten gibt, oder woran könnte es liegen?

(Die Größe meines Arrays beträgt immer die Breite meiner Darstellungskomponente, also momentan 470)

mfg,
heiopei
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#6

Re: Probleme mit Bereichsüberprüfung

  Alt 18. Okt 2007, 15:22
Es gibt von Punktanzahl eine Einschränkung auf 95/98/ME (siehe MSDN Polyline()) - diese liegt aber im schlechtesten Falle bei 1360 Punkten.

Aber mal eine andere Frage: wie gross werden denn deine Koordinaten? Dein Canvas ist ja nun nicht so gross als dass sie sehr gross werden, oder? Afair nutzt Polyline in Delphi doch TPoint und die wiederrum ShortInts und somit max. 16384 als Koordinatenwert.

Oder auch: Wie baust du das Array zusammen was du Polyline übrgibst? Kann es dabei sein, dass es nicht initialisierte Einträge gibt? z.B. Index 0 vergessen zu belegen? Gib mal bitte Code wie das Array deklariert wurde und wie es befüllt wird und den Aufruf von Polyline().
  Mit Zitat antworten Zitat
heiopei
(Gast)

n/a Beiträge
 
#7

Re: Probleme mit Bereichsüberprüfung

  Alt 18. Okt 2007, 16:57
hallo muetze1,

Zitat von Muetze1:
Es gibt von Punktanzahl eine Einschränkung auf 95/98/ME (siehe MSDN Polyline()) - diese liegt aber im schlechtesten Falle bei 1360 Punkten.
Den Hinweis habe ich bereits auch gelesen, da ich aber XP verwende, hab ich diese Einschränkung mal ignoriert.

Zitat:
Aber mal eine andere Frage: wie gross werden denn deine Koordinaten? Dein Canvas ist ja nun nicht so gross als dass sie sehr gross werden, oder? Afair nutzt Polyline in Delphi doch TPoint und die wiederrum ShortInts und somit max. 16384 als Koordinatenwert.
Ich verwende für die Koordinaten Integer-Variablen - ich wusste gar nicht, dass TPoint die Koord. als ShortInts speichert. Aber abgesehen davon müsste doch automatisch ein überlauf von Delphi bearbeitet werden, so dass für High(ShortInt)+1 Low(ShortInt) ergibt (Der Compilerschalter $Q ist bei mir momentan $Q-)?!?

Zitat:
Oder auch: Wie baust du das Array zusammen was du Polyline übrgibst? Kann es dabei sein, dass es nicht initialisierte Einträge gibt? z.B. Index 0 vergessen zu belegen? Gib mal bitte Code wie das Array deklariert wurde und wie es befüllt wird und den Aufruf von Polyline().
Kann grad nicht auf meinen Code zugreifen, da ich nicht daheim bin; aber ich bin mir ziemlich sicher, dass da nichts schief geht - werds auf jeden Fall nochmal prüfen und ggf. posten

danke für infos,
heiopei
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#8

Re: Probleme mit Bereichsüberprüfung

  Alt 18. Okt 2007, 19:17
Zitat von heiopei:
Aber abgesehen davon müsste doch automatisch ein überlauf von Delphi bearbeitet werden, so dass für High(ShortInt)+1 Low(ShortInt) ergibt (Der Compilerschalter $Q ist bei mir momentan $Q-)?!?
Da ein Überlauf ein Fehlverhalten ist, weiss ich nicht definitiv was hinten bei rauskommt. Auf der sichersten Seite ist man eh, wenn man erst gar nicht damit rechnet sondern lieber gleich entsprechend behandelt. Grundsätzlich würde ich die Überlaufprüfung/Bereichsprüfung einschalten und dann mal schauen ob es zu einer Meldung kommt. Grundlegend wüsste ich auch nicht wie dir mit negativen Koordinaten geholfen werden könnte (bei einem Überlauf), da der Canvas die doch dann eh nicht darstellt. Von daher wäre ein abfangen und entsprechend behandeln vllt. eine besser Alternative.

Naja, überprüfe mal dieses und dann schauen wir mal weiter...
  Mit Zitat antworten Zitat
heiopei
(Gast)

n/a Beiträge
 
#9

Re: Probleme mit Bereichsüberprüfung

  Alt 19. Okt 2007, 15:10
Hallo,
ich glaub, ich hab das Problem gelöst

Ausgehend von folgendem Code

Delphi-Quellcode:
const
  HI = 1234567;
  LO = -1234567;
var
  tmp: Double;
  res: Integer;
begin
  tmp := AlterWert / Skalierung;
  if tmp < LO then
    res := LO
  else
  if tmp > HI then
    res := HI
  else
    res := Round(tmp);
end;
habe ich durch try-and-error für den Konstantenwert "Lo" rausgefunden, dass genau vom Wechsel zw.
268435228 ($FFFFF1C) zu 268435229 ($FFFFF1D) der voher beschriebene Bluescreen auftritt!!!

Für HI ist der Wert High(Integer) möglich, allerdings werden dann beim zeichnen der Funktion für große x z.T. senkrechte Streifen gezeichnet (Die Streifen verschwinden erst für einen Wert der etwa |Lo| beträgt).

Daraus folgere ich, dass Windows intern eine Grenze von $7FFFFFF, bzw. - $FFFFF1D festgelegt hat!!!

Mein Code war also im Grunde genommen völlig korrekt, außer dass ich die falsche Negativ-Grenze verwendet habe

Naja, wieder mal was gelernt

Ich kann mir diesen krummen Wert zwar nicht erklären, aber was solls,

bis denne,
heiopei

PS:
Zitat:
Afair nutzt Polyline in Delphi doch TPoint und die wiederrum ShortInts und somit max. 16384 als Koordinatenwert.
In der OH steht, dass TPoint aus zwei Longint-Variablen besteht, also im endeffekt aus zwei Integer-Variablen -> -2^31 bis 2^31-1
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:13 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