Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Arrays gezielt über Grenzen hinaus beschreiben (https://www.delphipraxis.net/121702-arrays-gezielt-ueber-grenzen-hinaus-beschreiben.html)

Elko 2. Okt 2008 19:13


Arrays gezielt über Grenzen hinaus beschreiben
 
Hallöchen!
Hat jemand von euch eine Idee, wie man ein Array gezielt über das erste Element hinaus beschreiben kann?
Damit meine ich, dass folgender Code
Code:
unsigned char hallo[8],i,stelle=0,a=0;
for(i=0;i<8;i++)hallo[i]=0;
for(i=0;i<10;i++){
    *hallo |= (a<<stelle++);
    a=1;
}
printf("hallo= %x%x\n",hallo[1],hallo[0]);
das 3FE (hex) Ergebnis liefert.

Ich habe das ganze vorerst so gelöst:
Code:
unsigned char hallo[8],i,stelle=0,a=0;
for(i=0;i<8;i++)hallo[i]=0;
for(i=0;i<10;i++){
    if (stelle<8) hallo[0] |= (a<<stelle++);
    else if(stelle<16) hallo[1] |= (a<<(stelle++ -8));
    a=1;
}
printf("hallo= %x%x\n",hallo[1],hallo[0]);
Da es in diesem Programm um jede Millisekunde geht (und das ganze sehr oft aufgerufen wird), würde ich mich über eine bessere Lösung freuen :zwinker:
:dp:
Gruß,
Elko

mkinzler 2. Okt 2008 19:21

Re: Arrays gezielt über Grenzen hinaus beschreiben
 
Warum willst du das tun?

Dax 2. Okt 2008 20:26

Re: Arrays gezielt über Grenzen hinaus beschreiben
 
Ohne die Pointersemantik von C genau zu kennen, aber statt "*hallo" vielleicht "(long)(*hallo[0])*"?

Elko 2. Okt 2008 20:56

Re: Arrays gezielt über Grenzen hinaus beschreiben
 
Zitat:

Zitat von mkinzler
Warum willst du das tun?

Weil ich eine 64-Bit lange Zahl aus einzelnen Bits zusammensetzen muss und es dafür keinen Datentyp gibt. Daher hab ich ein Array aus 8 BYtes erstellt, was ja 64 Bit entspricht. Die Frage ist jetzt nur noch, wie ich diese "Zahl" aus einzelnen Bits zusammensetzen kann.

@Dax: Was meinst du denn?

Ein kleiner Hinweis noch dazu, was schiefläuft: Das erste Byte bekommt wie erwartet den Wert FE. Das zweite BYte, das ja eigentlich "3" enthalten müsste, ist aber immer noch "0"...

Gruß,
Elko

Dax 2. Okt 2008 21:09

Re: Arrays gezielt über Grenzen hinaus beschreiben
 
Code:
unsigned char hallo[8],i,stelle=0,a=0;
for(i=0;i<8;i++)hallo[i]=0;
for(i=0;i<10;i++){
    ((long*)(*hallo[0]))* |= (a<<stelle++);
    a=1;
}
printf("hallo= %x%x\n",hallo[1],hallo[0]);
Das meine ich ;) Aber wie gesagt, die Pointersemantik von C ist mir nicht ganz geläufig... Wenn du allerdings (bur) n 1-Bits und ein 0-Bits willst, wäre (1 << (n + 1)) ^ 1 vielleicht die bessere Alternative.

Apollonius 2. Okt 2008 21:11

Re: Arrays gezielt über Grenzen hinaus beschreiben
 
Vor das hallo[0] muss ein &, kein *, schließlich willst du die Adresse nehmen. Und zu deinem anderen Vorschlag, Dax: Müsste das nicht minus Eins statt xor Eins sein?

Dax 2. Okt 2008 21:16

Re: Arrays gezielt über Grenzen hinaus beschreiben
 
Oke, dann ein & - mir ist es wie gesagt selbst nicht ganz klar :)


Zitat:

Zitat von Apollonius
Müsste das nicht minus Eins statt xor Eins sein?

Nein. 3 1en und eine 0 ist 1110 - (1 << (n + 1)) - 1 ist 1000 - 1 = 111, mit ^ 1 dagegen sind es die gewünschten 1110.

Elko 2. Okt 2008 21:19

Re: Arrays gezielt über Grenzen hinaus beschreiben
 
Ahh, das ist schon mal ein guter Anfang:
Code:
unsigned char hallo[8],i,stelle=0,a=0;
for(i=0;i<8;i++)hallo[i]=0;
for(i=0;i<64;i++){
    *((long*)(&hallo[0])) |= (a<<stelle++);
    a=1;
}
printf("hallo= %x%x\n",hallo[1],hallo[0]);
So klappts ;-) Das Problem ist nur, dass ich nur beispielhaft lauter Einsen und eine Null reingeschoben habe und das mit den 10 Bits auch nur ein Test sein sollte. Insgesamt müssen es nämlich 64 Bit sein. Aber dafür gibt es ja m.E. keinen Datentyp...
Habt ihr noch eine Idee?

Gruß,
Elko

Dax 2. Okt 2008 21:25

Re: Arrays gezielt über Grenzen hinaus beschreiben
 
Das habe ich irgendwann mal gemacht. *g*
Code:
static void setBit(long* arr, int bit) {
  arr[bit >> (sizeof(long) * 8)] |= 1 << (bit & (sizeof(long) * 8 - 1);
}

static int getBit(long* arr, int bit) {
  return (arr[bit >> (sizeof(long) * 8] >> (bit & (sizeof(long) * 8 - 1)) & 1;
}
Sollte so funktionieren (denke ich)...

markusj 2. Okt 2008 21:28

Re: Arrays gezielt über Grenzen hinaus beschreiben
 
Zitat:

Zitat von Elko
Zitat:

Zitat von mkinzler
Warum willst du das tun?

Weil ich eine 64-Bit lange Zahl aus einzelnen Bits zusammensetzen muss und es dafür keinen Datentyp gibt. Daher hab ich ein Array aus 8 BYtes erstellt, was ja 64 Bit entspricht. Die Frage ist jetzt nur noch, wie ich diese "Zahl" aus einzelnen Bits zusammensetzen kann.

@Dax: Was meinst du denn?

Ein kleiner Hinweis noch dazu, was schiefläuft: Das erste Byte bekommt wie erwartet den Wert FE. Das zweite BYte, das ja eigentlich "3" enthalten müsste, ist aber immer noch "0"...

Gruß,
Elko

Kennst du int64_t und uint64_t, oder auch bekannt als long long und unsigned long long?
Include am besten einmal stdint.h ;) gehört afaik auch zum C-Standard.

Im übrigen müsstest du "einfach" nur hallo[stelle>>3] |= (a << (stelle++)%8) zuweisen, wenn ich dein Problem richtig verstanden habe.
Ersterer Teil greift auf das Element "stelle mod 8" zu, zweiterer schiebt das Bit dann zum Rest.

mfG
Markus

Apollonius 2. Okt 2008 21:31

Re: Arrays gezielt über Grenzen hinaus beschreiben
 
@Dax: Mit dem -1 hast du natürlich recht. Aber deine Lösung ist auch etwas komisch:
(1 << (n + 1)) ^ 1 = 10000 ^ 1 = 10001
Eigentlich müsste es also -2 sein, um aus 10000 1110 zu machen.

Dax 2. Okt 2008 21:31

Re: Arrays gezielt über Grenzen hinaus beschreiben
 
Zitat:

Zitat von markusj
Im übrigen müsstest du "einfach" nur hallo[stelle>>3] |= (a << (stelle++)%8) zuweisen, wenn ich dein Problem richtig verstanden habe.
Ersterer Teil greift auf das Element "stelle mod 8" zu, zweiterer schiebt das Bit dann zum Rest.

Das wäre zwar möglich, aber da Divisionen viele Zyklen kosten (und davon ne Menge), wäre dort eher ein & 7 angebracht. Allerdings wird dabei der Speicher auf Bytes heruntergebrochen statt auf machine words, was wieder zu Geschwindigkeitsverluste führt... Der Weg über (unsigned) longs und etwas Vertrauen in die CF-Unit des Compilers dürften da schon mehr wirken:)

Dax 2. Okt 2008 21:32

Re: Arrays gezielt über Grenzen hinaus beschreiben
 
Zitat:

Zitat von Apollonius
@Dax: Mit dem -1 hast du natürlich recht. Aber deine Lösung ist auch etwas komisch:
(1 << (n + 1)) ^ 1 = 10000 ^ 1 = 10001
Eigentlich müsste es also -2 sein, um aus 10000 1110 zu machen.

Oha, ups, Tatsache *g* Dann hattest du natürlich Recht, und ich hab ein -1 unter den Tisch fallen lassen. Entschuldige ;)

markusj 2. Okt 2008 21:55

Re: Arrays gezielt über Grenzen hinaus beschreiben
 
Zitat:

Zitat von Dax
Zitat:

Zitat von markusj
Im übrigen müsstest du "einfach" nur hallo[stelle>>3] |= (a << (stelle++)%8) zuweisen, wenn ich dein Problem richtig verstanden habe.
Ersterer Teil greift auf das Element "stelle mod 8" zu, zweiterer schiebt das Bit dann zum Rest.

Das wäre zwar möglich, aber da Divisionen viele Zyklen kosten (und davon ne Menge), wäre dort eher ein & 7 angebracht. Allerdings wird dabei der Speicher auf Bytes heruntergebrochen statt auf machine words, was wieder zu Geschwindigkeitsverluste führt... Der Weg über (unsigned) longs und etwas Vertrauen in die CF-Unit des Compilers dürften da schon mehr wirken:)

Ich programmiere C nur auf Atmel AVRs, daher die Denkweise ... bei nem 8-Bit RISC ist ein Byte das machine word ;)

mfG
Markus

Elko 2. Okt 2008 22:16

Re: Arrays gezielt über Grenzen hinaus beschreiben
 
Suuuuper! Danke an euch alle!!!
Jetzt funzts :thumb:
@markusj: Ich hab erstmal ne Weile rumgerätselt, was du geschrieben hast, aber letztendlich ists ja mal wirklich ne super einfache Lösung, ohne dass ich andere Datentypen benutzen muss :spin2: DANKE!

@Dax: Stimmt, das mit dem &7 ist sozusagen noch das i-Tüpfelchen für die Lösung :-D

Also hier nochmal der "fertige" Code, falls jemand in 20 Jahren das gleiche braucht :zwinker:
Code:
unsigned char hallo[8],i,stelle=0,a=0;
for(i=0;i<8;i++)hallo[i]=0;
for(i=0;i<64;i++){
  hallo[stelle>>3] |= (a << ((stelle++)&7));
  a=1;
}
Gute Nacht allerseits! :dp:
Elko


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:05 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