PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : falsche ergebnisse im mac



moedule
17-06-2004, 00:48
hey

ich hab schon vor längerem ein winziges programm geschrieben, mit dem man von einem meßprogramm geschriebene daten (binär) in menschlich lesbare (also ascii text) umwandelt (die ersten 1670 zeichen werden weggeschmissen, danach kommen 256 integer werte, die einfach mit nummerierung ausgegeben werden)



#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
FILE * ein;
int inFileArg=1;
int i,j;
int a[256];
int x;
char b[1670];

if (argc > 2 || argc == 1)
{
printf ("by Moe 2002\n");
printf("usage: programm datei\n");
}
else
{
ein = fopen(argv[inFileArg],"rb");
x=fread(b,sizeof(char), 1670,ein);
x=fread(a,sizeof(int), 256,ein);
for (i=0;i<256;i++)
{
printf("%i %i\n",i,a[i]);
}
fclose(ein);
}
}



unter linux (und windows ebenso), gibt ungefähr soetwas aus...


<snip>
232 0
233 0
234 1
235 0
236 0
237 0
238 0
239 0
240 0
241 0
242 2
243 1
244 1
245 1
246 1
247 0
248 0
249 0
250 1
251 0
252 0
253 0
254 0
255 0


einige meiner freunde haben einen mac und ich dachte kein problem, compilier ich es halt auf dem mac und gut ist. dem ist aber leider nicht so, denn wie man sehen kann kommen einfach die falschen werte dabei raus



<snip>
232 0
233 0
234 16777216
235 0
236 0
237 0
238 0
239 0
240 0
241 0
242 33554432
243 16777216
244 16777216
245 16777216
246 16777216
247 0
248 0
249 0
250 16777216
251 0
252 0
253 0
254 0
255 0


das ist jeweils das 16777216fache von den tasächlichen werten (leider stimmt das nicht überall, den bei besonders hohen werten stimts nicht, sonst könnte ichs ja leicht anpassen)

an was liegt das denn? kann mir das jemand erkären?? (bzw lösungsvorschlag) ich hab einfach noch nie mit dem mac was richtiges gemacht (programmiert) und deswegen steh ich da vor einem rätsel

wird wohl irgendwas mit dem integer zu tun haben nur genau was

moe

moedule
17-06-2004, 00:50
hm ok also nen überlauf muß ich auch noch korregieren, dann passt es

also wert = wert / 16777216 und wenn das kleiner als 0 ist dann noch 256-wert

trotzdem würde ich jetzt gerne wissen wodran das liegt

moe

Maledictus
17-06-2004, 01:43
ich bin mir jetzt nicht wirklich sicher, aber kann es sein, dass macs big-endian maschinen sind?

peschmae
17-06-2004, 06:59
Ja, die PowerPCs sind definitiv Big Endian Prozis.

MfG Peschmä

Pingu
17-06-2004, 07:14
Ersten das und zweitens ist int != int, denn je nach Architektur ist int 8-bit, 16-bit, 32-bit oder 64-bit. Deswegen lieber genau angeben als char, short int, long int oder long long.

Pingu

moedule
17-06-2004, 11:24
hey

ja mac ist wohl big endian

integer ist aber genau gleich groß wie beim x86, nämlich mit sizeof(int) jeweils 4

moe

Pingu
17-06-2004, 12:23
Original geschrieben von moedule
integer ist aber genau gleich groß wie beim x86, nämlich mit sizeof(int) jeweils 4
Stimmt nicht ganz: beim 8086/8088, die auch zur Familie der x86 gehören ist es 16-bit. Beim Athlon64 und beim G5 könnte ich mir 64-bit vorstellen (zumindest wenn der Compiler Standard-konform kompiliert), wissen tue ich es aber nicht.

Pingu

moedule
17-06-2004, 16:28
ich bin ja selber auf die idee mit den verschiedenen integer größen gekommen, und habs entsprechend ausprobiert ...

nur aufs big /litlle endian zeugs bin ich nicht gekommen

moe

Maledictus
17-06-2004, 20:44
Original geschrieben von Pingu
Stimmt nicht ganz: beim 8086/8088, die auch zur Familie der x86 gehören ist es 16-bit. Beim Athlon64 und beim G5 könnte ich mir 64-bit vorstellen (zumindest wenn der Compiler Standard-konform kompiliert), wissen tue ich es aber nicht.

Pingu

das hängt vom compiler hersteller ab. der c-standard schreibt afaik nur vor, dass ein int mindestens 2 byte gross ist. und ein byte mindestens 8 bit. es gibt auch systeme, wo ein byte 10 bit ist :D

moedule
19-06-2004, 14:16
nur mal so intresse halber , aber wie löst man das problem jetzt? ich habs mit htonl probiert (aus endian.h bzw ähnlichen) (also hostToNetwork(long)) bzw auch anders rum, aber es passiert nichts



int x=5;
int y;
y = htonl(x);


kommen genau die selben zahlen raus

moe

moedule
25-06-2004, 12:46
irgendwie will das ja nicht, mal dieses beispiel hier?? warum gibt das nicht den wert der int-variable i aus und dann den entsprechend bitvertauschten wert??



#include <stdio.h>
#include <arpa/inet.h>

int main()
{
int i;
for (i=0;i<100;i++)
printf ("%i %i\t",i, htonl(i));
}

brotzi
25-06-2004, 13:07
Weil htonl() von der Host zur Netzwerkbyteordnung wandelt. Die wird wohl auch BE sein.
Ich denke Du solltest beim Einlesen der Daten in ein struct-array lesen. Diese struct sollte 4 uchars haben. Dann machst Du eine Funktion, die von der Struct in int des jeweiligen Hostsystems wandelt. Weil die Quelldaten offenbar LE sind, ist die Funktion auf LE-Systemen sehr einfach. Auf BE-Systemen musst Du halt Bytes drehen um an das int zu kommen.

moedule
25-06-2004, 13:54
es ist aber gerade wurscht ob ich hton oder ntoh benutze die funktion ist im endeffekt die selbe

es hat nur keinerlei effekt

ich werd wohl tatsächlich diese struct variante gehen müssen

moe

moedule
25-06-2004, 15:58
so klappts, btw, danke an alle tippgeber

moe



#include <stdio.h>
#include <stdlib.h>

struct vierbyte{char a;char b;char c;char d;};

int little2big(struct vierbyte *w)
{
int r;
char h;

r = 0;
r = w->d & 255;
r = r << 8;
r = r + (w->c & 255);
r = r << 8;
r = r + (w->b & 255);
r = r << 8;
r = r + (w->a & 255);

return r;
}




int main(int argc, char **argv)
{
FILE * ein;
int inFileArg=1;
int i,j;
struct vierbyte a[256];
int x;
char b[1670];



if (argc > 2 || argc == 1)
{
printf ("by Moe 2002\n");
printf("usage: programm datei\n");
}
else
{
ein = fopen(argv[inFileArg],"rb");
x=fread(b,sizeof(char), 1670,ein);
x=fread(a,sizeof(struct vierbyte), 256,ein);
for (i=0;i<256;i++)
{
printf("%i %i\n",i,little2big(&a[i]));
}
fclose(ein);
}
}