Seite 1 von 2

TAP_Print und float

Verfasst: Di 2. Jan 2007, 21:36
von ibbi
Ich verzweifle gerade seit 2 Stunden an folgendem Stück Code und glaubte schon, ich wäre bei Versteckte Kamera:

Code: Alles auswählen

  float bps;
  TYPE_PlayInfo playinfo;

  TAP_Hdd_GetPlayInfo(&playinfo);

  bps = (float) playinfo.totalBlock / (60.0 * (float) playinfo.duration);

  TAP_Print("Block/s: %g (Blocks: %lu, Duration: %u, Seconds: %u)\n", bps, playinfo.totalBlock, playinfo.duration, playinfo.duration * 60);
Bei einer Aufname, von der ich weiß, dass sie 39315 Blocks hat und 127 Minuten lang ist (und dass 127 * 60 = 7620 ist), bekomme ich folgende Ausgabe:

Code: Alles auswählen

Block/s: 2.70025e-312 (Blocks: 2147483648, Duration: 39315, Seconds: 127)
:X

Welchen Schrott produziert TAP_Print denn hier?

AW: TAP_Print und float

Verfasst: Di 2. Jan 2007, 21:41
von Sigittarius-E
wie groß ist denn die Aufnahme? (in MB)

AW: TAP_Print und float

Verfasst: Di 2. Jan 2007, 21:42
von FireBird
Float produziert (zumindest mit unserer GCCforTAP) nur Müll. DeJe?

AW: TAP_Print und float

Verfasst: Di 2. Jan 2007, 21:48
von ibbi
[quote=""Sigittarius-E""]wie groß ist denn die Aufnahme? (in MB)[/quote]

3608 MB.

[quote=""FireBird""]Float produziert (zumindest mit unserer GCCforTAP) nur Müll. DeJe?[/quote]

Das stimmt so nicht. Ein (dword) bps enthält schon den korrekten Wert. Nur die Ausgabe von TAP_Print für float-Formate ist Müll.

AW: TAP_Print und float

Verfasst: Di 2. Jan 2007, 21:54
von Sigittarius-E
[quote=""ibbi""]3608 MB.[/quote]

Gibt es da nicht einen 2GB Bug von dem ich mal im Overfly und im MediaManager (UK Board) gelesen habe :thinker:

AW: TAP_Print und float

Verfasst: Di 2. Jan 2007, 22:12
von ibbi
[quote=""Sigittarius-E""]Gibt es da nicht einen 2GB Bug von dem ich mal im Overfly und im MediaManager (UK Board) gelesen habe :thinker: [/quote]

Was immer auch dies für ein Bug ist, der TAP_Print-float-Bug ist unabhängig davon:

Code: Alles auswählen

  float f;
  int i, j;

  f = 7.0 / 3.0;
  i = 1;
  j = 2;

  TAP_Print("%f %d %d\n", f, i, j);
  TAP_Print("%d %d %d\n", (int) f, i, j);
Ausgabe:

-0.000000 -1610612736 1
2 1 2


Macht echt Spaß. :?

Wenn DeJe jetzt schreibt, dass er diesen Bug nicht hat, steige ich auf den toolchain-Compiler um.

AW: TAP_Print und float

Verfasst: Di 2. Jan 2007, 23:32
von Homer
[quote=""ibbi""]Was immer auch dies für ein Bug ist, der TAP_Print-float-Bug ist unabhängig davon:

Code: Alles auswählen

  float f;
  int i, j;
 
  f = 7.0 / 3.0;
  i = 1;
  j = 2;
 
  TAP_Print("%f %d %d\n", f, i, j);
  TAP_Print("%d %d %d\n", (int) f, i, j);

Ausgabe:

-0.000000 -1610612736 1
2 1 2
[/quote]
Es sieht so aus, als ob f mehr Platz belegt als durch TAP_Print("%f",f) abgearbeitet wird.

Viele Grüße
Homer

AW: TAP_Print und float

Verfasst: Mi 3. Jan 2007, 14:07
von DeJe
Habs mal getestet.
Hier kommt der gleiche Müll raus. :(

AW: TAP_Print und float

Verfasst: Mi 3. Jan 2007, 14:12
von ibbi
[quote=""DeJe""]Habs mal getestet.
Hier kommt der gleiche Müll raus. :( [/quote]

Der Bug dürfte sich ja auch in der libtap.a (die es nur in einer Version gibt) befinden. Offenbar ist diese nicht mit soft-float-Support übersetzt worden, so dass das Format des übergebenen Fließkommawertes falsch interpretiert wird.

AW: TAP_Print und float

Verfasst: Mi 3. Jan 2007, 14:59
von DeJe
Ich habe eine eigene sprintf-Routine von der ich weiß das sie richtig funktioniert, auch mit Float-Ausgaben. Auf dem Topf kommt dort auch nur Müll raus (0.000000).

Es scheint auf dem Topf in der Tat am "float" selbst zu liegen. :thinker:

AW: TAP_Print und float

Verfasst: Mi 3. Jan 2007, 15:10
von ibbi
[quote=""DeJe""]Ich habe eine eigene sprintf-Routine von der ich weiß das sie richtig funktioniert, auch mit Float-Ausgaben. Auf dem Topf kommt dort auch nur Müll raus (0.000000).

Es scheint auf dem Topf in der Tat am "float" selbst zu liegen. :thinker: [/quote]

Kennst Du denn die interne Repräsentation von (soft-)float auf dem Topf? Oder benutzt Deine Routine %-Format-Funktionen der Bibliotheken?

Float-Operationen und Variablen selbst scheinen ja zu funktionieren, nur deren Formatierung nicht.

AW: TAP_Print und float

Verfasst: Mi 3. Jan 2007, 15:44
von DeJe
Hm, nein. Habe noch nicht geschaut ob die interne Repräsentation genau der des PC entspricht. Müßte ich mal vergleichen...

Edit: vorherige Aussage war falsch. Float ist nur 32 bit.

Aber irgendwie wird float falsch übergeben.

Wenn ich meinen Code folgendermaßen ändere:

Code: Alles auswählen

	unsigned int *pf;
	float f;

	f = 1.23456789;
	pf = (unsigned int *)&f;

	snprintf( 128, s_cMsg, "Float:%1.8f", *pf );
erhalte ich für "f" die richtige Ausgabe. Für ein normales

Code: Alles auswählen

snprintf( 128, s_cMsg, "Float:%1.8f", f );
aber nicht... :confused:

Die obere Variante funktioniert mit TAP_Sprint() übrigens nicht, es bleibt beim 0.00000

AW: TAP_Print und float

Verfasst: Mi 3. Jan 2007, 18:40
von Elle4u
[quote=""ibbi""]

Code: Alles auswählen

  TAP_Hdd_GetPlayInfo(&playinfo);
[/quote]
Hat zwar nur indirekt etwas mit Deiner Frage zu tun:

Immer darauf achten, die sicheren Aufrufe zu nehmen (Buffer overflow):

Code: Alles auswählen

// Workaround for TAP_Hdd_GetPlayInfo and TAP_Hdd_GetRecInfo buffer overrun bugs
bool Safe_TAP_Hdd_GetPlayInfo( TYPE_PlayInfo* playInfo )
{
  static TYPE_PlayInfo  safeInfo;
  static char           overrun[128];
  static int            overrunCheck;

  overrun[0] = 0;
  overrunCheck = 1;
  if ( !TAP_Hdd_GetPlayInfo( &safeInfo ) ) return FALSE;
  if ( overrunCheck != 1 ) TAP_Print( "TAP_Hdd_GetPlayInfo buffer overrun." );

  memcpy( playInfo, &safeInfo, sizeof(TYPE_PlayInfo) );

  return TRUE;
}

bool Safe_TAP_Hdd_GetRecInfo( byte recSlot, TYPE_RecInfo* recInfo )
{
  static TYPE_RecInfo   safeInfo;
  static char           overrun[128];
  static int            overrunCheck;

  overrun[0] = 0;
  overrunCheck = 1;
  if ( !TAP_Hdd_GetRecInfo( recSlot, &safeInfo ) ) return FALSE;
  if ( overrunCheck != 1 ) TAP_Print( "TAP_Hdd_GetRecInfo buffer overrun." );

  memcpy( recInfo, &safeInfo, sizeof(TYPE_RecInfo) );

  return TRUE;
}


AW: TAP_Print und float

Verfasst: Mi 3. Jan 2007, 18:43
von ibbi
[quote=""Elle4u""]Immer darauf achten, die sicheren Aufrufe zu nehmen (Buffer overflow):[/quote]

Ich weiß, wollte aber das Beispiel nicht unnötig verkomplizieren. :D :

AW: TAP_Print und float

Verfasst: Mi 3. Jan 2007, 19:47
von Homer
Funktioniert es denn mit double oder long double statt float?

Viele Grüße
Homer

AW: TAP_Print und float

Verfasst: Do 4. Jan 2007, 09:11
von ibbi
[quote=""Homer""]Funktioniert es denn mit double oder long double statt float?[/quote]

Double habe ich ausprobiert, geht auch nicht.

Gestern wollte ich schlau sein und mal sprintf oder snprintf versuchen, aber Topfield war schlauer. Das erste ist umdefiniert (TAP_SPrint) und funktioniert auch nicht, das zweite gibt es gar nicht.

Obwohl wir jetzt jemanden an der Quelle haben, hört man von einer neuen API ja leider auch nix mehr.

AW: TAP_Print und float

Verfasst: Do 6. Dez 2007, 21:59
von FireBird
Und hier ist die Erklärung.

AW: TAP_Print und float

Verfasst: Fr 7. Dez 2007, 09:33
von ibbi
[quote=""FireBird""]Und hier ist die Erklärung.[/quote]

Und das nach fast einem Jahr.

AW: TAP_Print und float

Verfasst: Fr 7. Dez 2007, 11:03
von ibbi
Wie wäre es denn dann mit etwas wie

Code: Alles auswählen

#define _f(x) ((dword *) &x)[0], ((dword *) &x)[1]
in der Lib?



Wie? Was? Ich soll das geschrieben geschrieben haben?! Niemals. :u:

AW: TAP_Print und float

Verfasst: Fr 7. Dez 2007, 12:09
von Homer
R2-D2 Posted: Fri. 07.12.2007 11:13:00
Adjusting the stack in TAP_Main() fixes it completely. DOH! I think the firmware could be patched to provide a proper fix, or TAPs that were bothered about it could have fixup wrappers on TAP_Main() and TAP_EventHandler().

Code: Alles auswählen

 
int TAP_Main(void) 
{ 
   char s[80]; 
   dword d=33; 
   double x=12345.67890, y=2121212.121212, z=-97979.797; 
__asm__ __volatile__ ("addiu $29,$29,-4\n"); 
   TAP_Print("x=%f y=%f d=%d z=%f\n",x,y,d,z); 
   TAP_SPrint(s,"x=%f y=%f d=%d z=%f\n",x,y,d,z); 
   TAP_Print(s); 
__asm__ __volatile__ ("addiu $29,$29,4\n"); 
   return 0; 
}
Viele Grüße
Homer