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)
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

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

[/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.

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.

[/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
aber nicht...
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""]
[/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.

:
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
in der Lib?
Wie? Was? Ich soll das geschrieben geschrieben haben?! Niemals.

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