SimkisenMedlem sedan jan. 200358 inlägg
hej hej
detta är C då...
jag har en liten array med numeriska värden.
där varje element är antingen 1 eller 0,
men nu är det så att jag skulle behöva lägga ihop
flera element till ett tal, inte plussa utan om elementen är
1,0,0,1 så vill jag kunna lägg ihop dom till 1001 så jag sen kan jämföra det talet mot nåt annat för att slippa jämföra varje element för sig.
tips någon?
PeWMedlem sedan juni 20006 839 inlägg
Ett elegant sätt:
int binarr(int *p,int n)
{
return (n>0)?*p+10*binarr(--p,n-1):0;
}
/* anropas med: resultat=10*binarr(arrayen+(längd-1),längd-1)+arrayens_sista_element;
vilket skulle ge med array "int t={1,0,0,1}": */
resultat=10*binarr(t+3,3)+t[3]
/*variabeln resultat har nu det decimala värdet 1001 */
Inlägget redigerat p.g.a att det kanske rör sig om en skoluppgift och det första svaret var lite väl enkel kod. Tankegången är dock densamma :)
SimkisenMedlem sedan jan. 200358 inlägg
din kod funkar inte.
resultat får värdet 11 eller 11.000000
och jag hajjade typ inget av det där.
visst det handlar om en skoluppgift men det där är en liten liten del av ett stort program som vi ska göra. ska nämligen göra ett program som läser in bitar ur en mp3 fil och skriver ut samplingsfrekvens och dylikt.
jag har fått ut bitarna men istället för att jämföra dom i 4 steg med 4 bitar för att få ut vilken samplingsfrekvens det är så vill jag hellre jämföra i ett steg med ett tal.
PeWMedlem sedan juni 20006 839 inlägg
Simkisen skrev:
din kod funkar inte.
resultat får värdet 11 eller 11.000000
Ojdå. Det är klart att det blir så när basen är 0. Dumt av mig. Basen ska så klart vara *p och då fås följande uppdaterade kod:
int binarr(int *p,int n)
{
return (n>0)?*p+10*binarr(--p,n-1):*p;
}
Som nu anropas med:
resultat = binarr(t+längd-1,längd-1);
Koden fungerar ivf nu, när jag kör den, med samtliga 16 varianter (0000,0001,0010... 1111).
och jag hajjade typ inget av det där.
Den rekursiva funktionen jobbar ned sig från det sista elementet i arrayen till det första. På sin resa lägger den till potens och det aktuella talet på den positionen.
visst det handlar om en skoluppgift men det där är en liten liten del av ett stort program som vi ska göra.
Men det förutsätts kanske att ni läst på om programmering? Den här uppgiften går ivf att lösa genom en for-loop som stegar sig fram i arrayen och lägger på potens och det aktuella talet i en variabel. Men det är inte lika vackert och väldigt basic :p
ska nämligen göra ett program som läser in bitar ur en mp3 fil och skriver ut samplingsfrekvens och dylikt.
jag har fått ut bitarna men istället för att jämföra dom i 4 steg med 4 bitar för att få ut vilken samplingsfrekvens det är så vill jag hellre jämföra i ett steg med ett tal.
Om jag nu fattar dig rätt så plockar ni ut ett bitmönster och översätter varje bit till en 32bitars representation (int arrayens varje element) för att sedan transformera det vidare till en 32bitars representation för att sen kunna jämföra med ett annat tal? Isf är det väl bättre ur prestandasynpunkt att läsa in bitmönstret som ett 32bitars tal direkt eller maska ut ett eventuellt svar direkt? Okej, det kanske är en overkill-optimering i erat fall, men ändå :)
PeWMedlem sedan juni 20006 839 inlägg
En 'enklare' variant kan ivf se ut så här:
int i,res;
for(i=0,res=0,i<_array_längd_;i++)
{
res*=10;
res+=_array[i];
}
resultatet finns nu i variabeln res
SimkisenMedlem sedan jan. 200358 inlägg
jag kan inte det där med att maska ut tal o så,
men jag lyckades läsa ut vad 3e byten i filen är för nåt heltal och sen göra om den till en binär array.
finns säkert lättare sätt, men det är den jag lyckats åstadkomma själv.
och nu ska jag jämföra dom 4 första bitarna för att få fram bitraten och sen ta ut bit nummer 5 o 6 för att ta reda på samplingsfrekvensen.
tror jag ska använda mig utav en variant av den eklare varianten i såna fall. gör om den till en funktion så jag kan välja vilka bitar den ska läsa in.
SimkisenMedlem sedan jan. 200358 inlägg
som du ser är detta en variant på den enklare som du skrev.
men skickar med en array med bitarna, var i arrayen den ska börja och hur många bitar den ska ta med.
typ:
resultat=binarr(array,0,4);
så läser den 4 bitar från och med element 0 =D
varför jag har med start element är enkelt för jag har läst ut en byte och lagrat bitarna i en array där 4 första bitarna talar om vilken bitrate det är i filen och bit 5-6 talar om vilken frekvens det är.
int binarr(int a[],int i,int n)
{
int res,k;
k=n+i;
for(res=0;i<k;i++)
{
res*=10;
res+=a[i];
}
return res;
}
visst, det här var en mycket enkelfunktion när man väl tänker efter och det skulle jag nog kunnat komma på själv egentligen, men jag låste mig på bitarna och att få det till ett tal så det gick inte så bra. i PHP skulle man bara kunnat lägga ihop siffrorna till en sträng, men det går ju inte i C.
PeWMedlem sedan juni 20006 839 inlägg
Simkisen skrev:
där 4 första bitarna talar om vilken bitrate det är i filen och bit 5-6 talar om vilken frekvens det är.
Isf är det väl enklare att läsa in de första 32 bitarna (förutsatt en 32-bitars plattform) rakt av iform av en int och sen skifta ut det du vill ha med:
int input=_läs_in_en_int_från_fil_
int bitrate=(input>>12); //skifta ut de 4:a högsta bitarna
int frequence=(input>>10)&3; //skifta ut de 6 högsta bitarna och maska bort de 4:a första
Med en sekvens om "1111 11** **** ****" (*=vadsomhelst) blir resultatet i bitrate 15 och resultatet i frequence 3.
Red: Tänkte fel vad det gäller skift och 32bitar på en PC
SimkisenMedlem sedan jan. 200358 inlägg
ok, men jag tar ut en byte (8 bitar) till en short int, gör om den till en array med bitar och från dom bitarna gör jag det jag behöver veta till ett tal och sen tar ut rätt frekvens eller bitrate beroende på vilket jag behöver veta.
båda står med i tredje byten i mp3-filen.
vill du se hur frameheadern i mp3-filen ser ut kan du ju kolla på den här länken
jag har ju som sagt redan löst det på mitt sätt, hela frame headern är ju 32 bitar så man kan ju ta ut den till en long int då väl och sen ta ut rätt bitar på nåt sätt. fast jag hajjade inte riktigt det där, vi fick med i uppgiften att man kunde kolla närmare på &-operatorn för att kunna lösa det smidigt, och det e väl det du har använt med >> har jag för mig? fast jag fattade inte hur det fungerade då jag läste om det.
fattade inte heller riktigt hur du gjorde det där, men om jag förstått rätt så blir det som jag gjort bara att du maskar ut rätt del försig som ett heltal, som man sen kan jämföra eller krångla till det till en int som ser ut som det man maskade och jämföra det sen.
för bitarna 1,1,1,1 = 15 och 1,1 = 3??
om du läser in hela frameheadern då som 32 bitar då hamnar ju bitrate på bitarna 17-20 och frekvens på 21-22 hur maskar du då fram rätt bitar till en int som du gjort nu?
PeWMedlem sedan juni 20006 839 inlägg
Simkisen skrev:
ok, men jag tar ut en byte (8 bitar) till en short int, gör om den till en array med bitar och från dom bitarna gör jag det jag behöver veta till ett tal och sen tar ut rätt frekvens eller bitrate beroende på vilket jag behöver veta.
båda står med i tredje byten i mp3-filen.
vill du se hur frameheadern i mp3-filen ser ut kan du ju kolla på den här länken
jag har ju som sagt redan löst det på mitt sätt, hela frame headern är ju 32 bitar så man kan ju ta ut den till en long int då väl och sen ta ut rätt bitar på nåt sätt. fast jag hajjade inte riktigt det där, vi fick med i uppgiften att man kunde kolla närmare på &-operatorn för att kunna lösa det smidigt, och det e väl det du har använt med >> har jag för mig? fast jag fattade inte hur det fungerade då jag läste om det.
fattade inte heller riktigt hur du gjorde det där, men om jag förstått rätt så blir det som jag gjort bara att du maskar ut rätt del försig som ett heltal, som man sen kan jämföra eller krångla till det till en int som ser ut som det man maskade och jämföra det sen.
för bitarna 1,1,1,1 = 15 och 1,1 = 3??
om du läser in hela frameheadern då som 32 bitar då hamnar ju bitrate på bitarna 17-20 och frekvens på 21-22 hur maskar du då fram rätt bitar till en int som du gjort nu?
Det var bara ett förslag som jag gav dig, du kan såklart göra hur du vill :)
Men för att en maskning ska stämma med kraven i länken du angav blir de enligt följande:
int input = _hela headern från filen_
int bitrate = (input >> 12) & 15;
int frequency = (input >> 10) & 3;
bitrate innehåller nu ett tal 0-15 och frequency ett tal 0-3.
>> operatorn skiftar ett (angivet) antal steg i ett bitmönster åt höger.
(1100)>>2 ger (0011)
& operatorn maskar ut motsvarande angivna bitar
(1100) & (0100) ger (0100) iom att det bara är den tredje biten de har gemensamt som samtidigt är 1.
SimkisenMedlem sedan jan. 200358 inlägg
ok, ska kolla lite närmare på det där imorgon eller ikväll tror jag.
jag testade mitt program på Linux på skolan, men fick då segmentation fault, vilket inte låter så bra. programmet fungerade ju perfekt på windows för mig med GCC som kompilator som dom även har på linuxet i skolan.
och segmentation fault säger inte mig nånting, och man får ju inte med nån kommentar som säger var det är fel heller. så det kan bli lite jobbigt o fixa.
du råkar inte ha nån aning om hur segmentation fault kan uppstå? jag läste nåt om att det kan uppstå vid division. och det använder jag mig av när jag gör en int till en array med binära tal. e de möjligt att det är det som orsakar felet?
PeWMedlem sedan juni 20006 839 inlägg
Segment fault är exempelvis om en pekare pekar i ej giltigt minnesutrymme eller om indexering av en array går utanför arrayen. För sånt är debuggern (dbg + DDD) ett bra verktyg i linux för att syna adressering, det finns även lib att inkludera som talar om direkt ifall ens kod skulle kunna ge segment fault (ex. Electric Fence).
Att inte felet uppstod i windows säger inte så mycket då en segment fault kanske inte uppdagas direkt utan inträffar först när det i just den situationen i just det minnesutrymmet ger en krasch. Buggen finns där ändå, alltså, även om den inte alltid utlöses. Se det som att körningen i linux uppmärksammade dig på problemet snarare än att programmet var korrekt i windows :bire
SimkisenMedlem sedan jan. 200358 inlägg
aha, okej, eftersom jag testat programmet många gånger i windows och aldrig fått felet men fick det varje gång i linux så var det lite konstigt.
med hjälp av läraren så fick vi ordning på det där och det var att istället för att läsa en byte från filen så läste den mycket mer i linux, men med lite fifflande med variablerna så fick vi den o bara läsa en byte. och sen löste det sig.
segmentation fault uppstod alltså pga linux läste in mer än vad den skulle göra och därmed blev det fler än 8 bitar som skulle sparas och eftersom dom var fler än 8 typ 16 eller nåt så fick inte alla plats i arrayen som bara hade plats för 8 bitar.
istället för att fiffla om variablerna skulle detta säkert kunnat lösas genom att bara ge mer plats åt bitarna i arrayen.
PeWMedlem sedan juni 20006 839 inlägg
Det där beror kanske inte nödvändigtvis på Linux utan kanske lika gärna på hur Posix-standarden används i Windows (open file, read file m.m). Såvitt jag vet är posix stödet större i Linux än i windows, men jag kan ju ha fel (har ju hänt förr). I vilket fall blir det ett segmentation fault därför att du rotade i minnesutrymme som du inte hade tillgång till.
Ifall du konsekvent läser in hela headern som en 'int' istället och använder maskning så slipper du liknande plattforms-specifika problem samt den overhead det innebär att skyffla byten och konvertera till int'ar i en array samt följande bearbetning. ;) :p
SimkisenMedlem sedan jan. 200358 inlägg
oki doki =)
kollade på det där med maskning innan jag började, men då fattade jag ingenting så jag gjorde det på mitt sätt och det funkade ju också. inte lika bra dock, men det var ett godkänt sätt =)
ska kolla närmare på maskning sen när det behövs =) men nu har du ju förklarat närmare om det så jag har ett visst hum om hur det fungerar iaf =)
PeWMedlem sedan juni 20006 839 inlägg