AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi FLOAT_INVALID_OPERATION und FLOAT_OVERFLOW nur 64Bit

FLOAT_INVALID_OPERATION und FLOAT_OVERFLOW nur 64Bit

Ein Thema von venice2 · begonnen am 15. Jul 2021 · letzter Beitrag vom 19. Jul 2021
Antwort Antwort
venice2
(Gast)

n/a Beiträge
 
#1

AW: FLOAT_INVALID_OPERATION und FLOAT_OVERFLOW nur 64Bit

  Alt 16. Jul 2021, 11:34
Es setzt sich so zusammen.

In Create erstelle ich einen Temporären DC
TempBufferDC := gSprVizC.GI_Create32bitDC(255, 60, $00000000);
Delphi-Quellcode:
procedure TBassPlayer.DrawData;
var
  k: integer;
  TRA: array[1..512] of single;
  TIA: array[1..512] of single;
begin

  // Fülle das Array mit den Wave Daten
  for k := 0 to 511 do
    TRA[k + 1] := WaveData[k] / 1.50;

  XFFT(TRA, TIA, -1, 1, 512); // Wave Daten glätten

  for k := 1 to 512 do // PicFlame auf den TempBufferDC Blitten
  begin
    if TRA[k] < 0 then
      TRA[k] := 0;

    BitBlt(TempBufferDC, k - 1, trunc(Abs(FHeight - TRA[k])), 1, FHeight,
      PicFlame[FCurentFlame].Canvas.Handle, 0, 0, SRCCOPY);
  end;

  FadeBackBuffer(TempBufferDC); // Inhalt vom TempBufferDC Faden

  BitBlt(PaintDC, 0, 0, FWidth, FHeight, TempBufferDC, 0, 0, SRCCOPY);
procedure TBassPlayer.XFFT(FR, FI: array of single; Sign, Sample, SampleCount: Integer);
Zitat:
also die Indizes 0..SampleCount-1.
for Q := Sample to (SampleCount) do
Zitat:
Weiß nicht, ab das das Problem ist.
Wenn die Schleifen nicht korrekt wären dürfte es auch unter 32Bit nicht laufen.

Wenn es jemand testen möchte schicke ich ihm gern den Quelltext zu.

Geändert von venice2 (16. Jul 2021 um 11:45 Uhr)
  Mit Zitat antworten Zitat
brechi

Registriert seit: 30. Jan 2004
823 Beiträge
 
#2

AW: FLOAT_INVALID_OPERATION und FLOAT_OVERFLOW nur 64Bit

  Alt 16. Jul 2021, 16:13
Bei mir läuft der bei deinen Angaben schon direkt in eine Endlosschleife, weil M irgendwann 0 ist:
Delphi-Quellcode:
      M := ((SampleCount + 1) div 2);
      while M < J do
      begin
        J := J - M;
        M := M div 2;
      end;
      J := J + M;
Da in der zweiten Schleife le1 immer größer wird
Delphi-Quellcode:
      le := trunc(Power(2, L));
      le1 := le div 2;
und dann irgendwann
Delphi-Quellcode:
ip := Q + (le1 - 1);

// mit
 while Q <= (SampleCount + 1) do

auf außerhalb des arrays Zugegriffen wird
Delphi-Quellcode:
  
tr := FR[ip] * ur - FI[ip] * ui; // FLOAT_INVALID_OPERATION nur 64Bit
ti := FR[ip] * ui + FI[ip] * ur;
kann nur murks bei rumkommen. Das wird auch unter 32Bit keine korrekten Ergebnisse liefern, sondern nur zufällig laufen, je nachdem was gerade auf dem Heap ist.

Bau mal ein:

Delphi-Quellcode:
ip := Q + (le1 - 1);

          if ip > High(fi) then
            raise Exception.Create('Fehler');
          if ip > High(FR) then
            raise Exception.Create('Fehler');

          tr := FR[ip] * ur - FI[ip] * ui; // FLOAT_INVALID_OPERATION nur 64Bit
          ti := FR[ip] * ui + FI[ip] * ur;
ein

Geändert von brechi (16. Jul 2021 um 16:16 Uhr)
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.100 Beiträge
 
Delphi XE2 Professional
 
#3

AW: FLOAT_INVALID_OPERATION und FLOAT_OVERFLOW nur 64Bit

  Alt 16. Jul 2021, 16:21
@venice2:

Ich glaube da machst du einen Denkfehler.

In "TBassPlayer.DrawData" sind TRA und TIA zwar als Array[1..512] of Single, also statische Arrays deklariert.
Aber an procedure TBassPlayer.XFFT(FR, FI: array of single; Sign, Sample, SampleCount: Integer); .
werden die TRA und TIA als dynamische Arrays übergeben und haben dort die Indizes 0..511, SampleCount jedoch hat den Wert 512.
Wenn du in "TBassPlayer.XFFT" das while Q <= (SampleCount + 1) do abarbeitest kommt es 2 mal zu Bereichsüberschreitungen.
Das erste mal wenn Q = 512 ist.
Das zweite mal wenn Q = 513 ist, denn die while Schleife arbeitet ja nicht nur bis SampleCount sondern sogar bis SampleCount+1.
In beiden Fällen wird nicht auf Inhalte der Arrays zugegriffen, sondern auf irgendwelche Daten, die zufälligerweise an den Adressen stehen,
auf die zugegriffen wird
Die Fehlermeldung FLOAT_INVALID_OPERATION deutet darauf hin, dass mit einer ungültigen Fließkommazahl, z.B. einer NaN irgendetwas
gerechnet wird.
Die Fehlermeldung FLOAT_OVERFLOW sagt, dass das Rechenergebnis außerhalb des für Singles gültigen Bereiches ist.

Richtig wäre also, wie bereits in #7 gesagt: while Q < SampleCount .

Zitat:
Wenn die Schleifen nicht korrekt wären dürfte es auch unter 32Bit nicht laufen.
Vielleicht stehen unter 32 Bit an den Adressen außerhalb der Arrays 0 Werte und unter 64 Bit z.B. NaNs.
Dann hättest du unter 32 Bit zwar fehlerhafte Ergebnisse aber keine Exeptions, unter 64 Bit dagegen würden dann Exceptions ausgelöst.
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
venice2
(Gast)

n/a Beiträge
 
#4

AW: FLOAT_INVALID_OPERATION und FLOAT_OVERFLOW nur 64Bit

  Alt 16. Jul 2021, 17:17
Zitat:
Vielleicht stehen unter 32 Bit an den Adressen außerhalb der Arrays 0 Werte und unter 64 Bit z.B. NaNs.
Dann hättest du unter 32 Bit zwar fehlerhafte Ergebnisse aber keine Exeptions, unter 64 Bit dagegen würden dann Exceptions ausgelöst.
Das mag sein.
Danke für deine Ausführliche Erklärung.
Werde es mal testen.

EDIT:
Nein geht nicht hatte das Extended noch definiert.
Kommen die gleichen Fehler mit Single.

Habe deine Änderung trotzdem belassen da es mir schlüssig erscheint. Danke!

Geändert von venice2 (16. Jul 2021 um 17:57 Uhr)
  Mit Zitat antworten Zitat
brechi

Registriert seit: 30. Jan 2004
823 Beiträge
 
#5

AW: FLOAT_INVALID_OPERATION und FLOAT_OVERFLOW nur 64Bit

  Alt 16. Jul 2021, 19:53
Hast du denn mal den rangecheck eingebaut?
  Mit Zitat antworten Zitat
venice2
(Gast)

n/a Beiträge
 
#6

AW: FLOAT_INVALID_OPERATION und FLOAT_OVERFLOW nur 64Bit

  Alt 16. Jul 2021, 19:58
Hast du denn mal den rangecheck eingebaut?
Das sind Grundvoraussetzungen.
  Mit Zitat antworten Zitat
brechi

Registriert seit: 30. Jan 2004
823 Beiträge
 
#7

AW: FLOAT_INVALID_OPERATION und FLOAT_OVERFLOW nur 64Bit

  Alt 16. Jul 2021, 20:06
Delphi-Quellcode:
//...
ip := Q + (le1 - 1);

          if ip > High(fi) then //rangecheck
            raise Exception.Create('Fehler');
          if ip > High(FR) then
            raise Exception.Create('Fehler');

          tr := FR[ip] * ur - FI[ip] * ui; // FLOAT_INVALID_OPERATION nur 64Bit
          ti := FR[ip] * ui + FI[ip] * ur;
Läuft das bei dir durch, oder wird ein Fehler angezeigt?
  Mit Zitat antworten Zitat
venice2
(Gast)

n/a Beiträge
 
#8

AW: FLOAT_INVALID_OPERATION und FLOAT_OVERFLOW nur 64Bit

  Alt 16. Jul 2021, 20:15
Delphi-Quellcode:
//...
ip := Q + (le1 - 1);

          if ip > High(fi) then //rangecheck
            raise Exception.Create('Fehler');
          if ip > High(FR) then
            raise Exception.Create('Fehler');

          tr := FR[ip] * ur - FI[ip] * ui; // FLOAT_INVALID_OPERATION nur 64Bit
          ti := FR[ip] * ui + FI[ip] * ur;
Läuft das bei dir durch, oder wird ein Fehler angezeigt?
Falls hier ein Fehler auftreten sollte und ich habe unter den Option die Bereichsprüfung eingeschaltet dann sollte der Debugger einen Fehler melden oder?
Aber ich kann es auch mal auf diese weise versuchen. Danke!

Das ist was ich meinte mit Grundvoraussetzung.

EDIT:
Aber der rangecheck hat nichts mit FLOAT_INVALID_OPERATION zu tun oder?
Habe es versucht.
FLOAT_INVALID_OPERATION kommt trotzdem auch mit deinem rangecheck

Geändert von venice2 (16. Jul 2021 um 20:19 Uhr)
  Mit Zitat antworten Zitat
brechi

Registriert seit: 30. Jan 2004
823 Beiträge
 
#9

AW: FLOAT_INVALID_OPERATION und FLOAT_OVERFLOW nur 64Bit

  Alt 16. Jul 2021, 20:42
Die Frage ist, ob die die Range-Prüfung ausgelöst wird. Wenn FLOAT_INV.. vorher kommt, liegt es zumindest nicht daran, dass du auf einen ungültigen Speicherbereich zugreift.
Wenn du auf Speicherbereich nach dem Array zugreift würdest, dann kann dadurch schon der Fehler FLOAT_INV ausgelöst werden, je nachdem was dort steht.
Da wie bereits erwähnt ein array of single bei 0 startet müsste auch sample bei 0 beginnen und auch in die anderen beiden schleifen dürften immer nur bis samplecount-1 laufen.

Geändert von brechi (16. Jul 2021 um 20:50 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 01:26 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz