Avatar billede Slettet bruger
10. februar 2009 - 16:07 Der er 29 kommentarer og
1 løsning

Toggle bestemt bit i string?

Hej eksperter,

Først skal det lige siges, at jeg ikke er voldsomt god til C++.

Jeg skal have toggled en bit i en string - hvordan gør jeg det?
Eksempel: "AB" (0100 0001, 0100 0010 ASCII) bliver til 0100 0011, 0100 0000 ved toggle af bit 6.
Avatar billede Slettet bruger
10. februar 2009 - 16:09 #1
Bemærk at eksemplet er ret dårligt, da det viser en ændring af 6. bit i hver byte - her kommer et bedre:

Eksempel: "AB" (0100 0001, 0100 0010 ASCII) bliver til 0100 0001, 0100 0000 ved toggle af bit 14.
Avatar billede arne_v Ekspert
10. februar 2009 - 16:22 #2
offset / 8 er byte nummer
offset % 8 er bit nummer i byte
du kan bruge det
Avatar billede arne_v Ekspert
10. februar 2009 - 16:24 #3
utestet:

s[offset/8] |= (1 << offset%8);
Avatar billede arne_v Ekspert
10. februar 2009 - 16:26 #4
den saetter

for at cleare:

s[offset/8] &= ~(1 << offset%8);
Avatar billede Slettet bruger
10. februar 2009 - 21:12 #5
Mh. Er det ikke muligt at spare et par operationer ved at skrive
s[i] ~= 1
?
Avatar billede Slettet bruger
10. februar 2009 - 21:15 #6
Altså, hvor i er den kendte bit i strengen.
Avatar billede arne_v Ekspert
10. februar 2009 - 21:49 #7
Nej.

char index er byte index ikke bit index
Avatar billede Slettet bruger
10. februar 2009 - 21:51 #8
Hvordan kan jeg så manipulere en enkelt bit uden alt for meget fiksfakseri? Er der ikke en let metode til det?
Det kan godt ske, jeg skal have læse lidt om bithåndtering i C/C++... Kender du en god artikel/tutorial?
Avatar billede arne_v Ekspert
10. februar 2009 - 22:16 #9
Som jeg har vist. Det er ikke saa svaert.

Det er mest et spoergsmaal om at kende de bitvise operatorer.

C kode og C# kode vil se stort set ens ud.
Avatar billede arne_v Ekspert
10. februar 2009 - 22:32 #10
C:

#include <stdio.h>

void bitset(unsigned char *ba, int ix)
{
    ba[ix / 8] |= (1 << ix % 8);
}

void bitclr(unsigned char * ba, int ix)
{
    ba[ix / 8] &= ~(1 << ix % 8);
}

int bittst(unsigned char *ba, int ix)
{
    return ba[ix / 8] & (1 << ix % 8);
}

int main()
{
    int i;
    unsigned char b[] = { 0, 255 };
    printf("%2X %2X\n", b[0], b[1]);
    for(i = 0; i < 16; i++) printf("%c", bittst(b, i) ? '1' : '0');
    printf("\n");
    bitset(b, 2);
    bitclr(b, 10);
    printf("%2X %2X\n", b[0], b[1]);
    for(i = 0; i < 16; i++) printf("%c", bittst(b, i) ? '1' : '0');
    printf("\n");
    return 0;
}
Avatar billede arne_v Ekspert
10. februar 2009 - 22:33 #11
C#:

using System;

namespace E
{
    public static class BitFun
    {
        public static void BitSet(byte[] ba, int ix)
        {
            ba[ix / 8] = (byte)(ba[ix / 8] | (1 << ix % 8));
        }
        public static void BitClr(byte[] ba, int ix)
        {
            ba[ix / 8] = (byte)(ba[ix / 8] & ~(1 << ix % 8));
        }
        public static bool BitTst(byte[] ba, int ix)
        {
            return (ba[ix / 8] & (1 << ix % 8)) != 0;
        }
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            byte[] b = { 0, 255 };
            Console.WriteLine(b[0].ToString("X2") + " " + b[1].ToString("X2"));
            for(int i = 0; i < 16; i++) Console.Write(BitFun.BitTst(b, i) ? '1' : '0');
            Console.WriteLine();
            BitFun.BitSet(b, 2);
            BitFun.BitClr(b, 10);
            Console.WriteLine(b[0].ToString("X2") + " " + b[1].ToString("X2"));
            for(int i = 0; i < 16; i++) Console.Write(BitFun.BitTst(b, i) ? '1' : '0');
            Console.WriteLine();
        }
    }
}
Avatar billede arne_v Ekspert
10. februar 2009 - 22:33 #12
Jeg husker rigtigt - at du ogsaa kode C# ?
Avatar billede Slettet bruger
11. februar 2009 - 21:23 #13
Hehe, jo, jeg skriver også C#... Og jeg er en del bedre til det end C/C++.
Jeg prøver lige med C#-koden, for det ser ud til, at det er mindst lige så enkelt og effektivt(?) som C/C++.
Avatar billede Slettet bruger
11. februar 2009 - 21:25 #14
Der er forresten noget, der slår mig: Hvad nu hvis strengen er længere end maksimalværdien for int? Så kan den vel ikke opstilles som et char array?
Avatar billede arne_v Ekspert
11. februar 2009 - 21:29 #15
C# har udmaerket support for bit manipulation.

Man skal dog caste list mere end i C.

Jeg ville heller ikke blive overrasket hvis C var lidt hurtigere end C# til lige netop dette formaal.
Avatar billede arne_v Ekspert
11. februar 2009 - 21:31 #16
Du faar problem hvis dit C char array / C# byte array skal have mere end 2 milliarder elementer.

(C# saadan er det, C ved de mest gaengse implementationer)

Allerede ved 200 millioner skal ix aendres til en 64 bit integer.
Avatar billede Slettet bruger
11. februar 2009 - 21:41 #17
Mhm. Faktisk er jeg lidt en klovn, har jeg lige fundet ud af. Koden skulle være kernen i en virtuel makulator, der toggler bits med tilfældige intervaller (0-2 for perfekt destruktion), men når jeg alligevel håndterer hele strengen på én gang, skal jeg jo også skrive hele den resulterende streng (eller byte array) til filen - hvorfor jeg lige så godt kan unsette samtlige bits :) Lidt af en bommert.
Anyway, jeg tester det alligevel og ser, om jeg kan få det til at du.
Avatar billede arne_v Ekspert
11. februar 2009 - 21:49 #18
Det vil da give god mening at overskrive filen med random data (husk ikke at slette den gamle fil og skrive en ny fil !).

Men du kan jo sagtens goere det byte vis fremfor bit vis.
Avatar billede Slettet bruger
11. februar 2009 - 21:56 #19
Okaj, jeg tror ikke helt, jeg fik forklaret problemet godt nok :)
Konceptet går ud på ikke at overskrive hver eneste byte, da dette for store filer vil tage meget lang tid. I stedet toggles enkelte bits med f.eks. 0 til 14 (gennemsnit 7) bits interval, hvor med der opnås 0 til 8 og statistisk set 1 "fejl" i hvert bit af hele filen, hvilket gør genskabelsesarbejdet voldsomt stort i forhold til den lette makulering. Pointen er så, at der selvfølgelig kun skal skrives til filen, hvor en bit er ændret - ellers kan jeg jo lige så godt droppe algoritmen og skrive rene 0'er, for så er der jo intet sparet på hverken CPU, RAM eller HD - tværtimod!
Avatar billede Slettet bruger
11. februar 2009 - 21:59 #20
hvor med der opnås 0 til 8 og statistisk set 1 "fejl" i hvert bit af hele filen

skulle være

hvormed der opnås 0 til 8 og statistisk set 1 "fejl" i hvert byte af hele filen
Avatar billede arne_v Ekspert
11. februar 2009 - 22:00 #21
Det tjener ikke noget formaal. File laeses og skrives i store klumper. KB ! Om du aendrer 1 bit eller samtlige bit i de KB boer ikke paavirke performance naevnevaerdigt.
Avatar billede arne_v Ekspert
11. februar 2009 - 22:03 #22
Men se positivt paa det. Bit manipulation med &|~<<>> er en del af almindelig dannelse !

Har du ioverigt laest http://www.eksperten.dk/guide/505 ?
Avatar billede Slettet bruger
12. februar 2009 - 00:04 #23
#21
Se, det er problemet med at være kreativ frem for vidende :) Tak.

#22
Jeps, jeg har sprunget over mange aspekter af programmering, da jeg alligevel starter mit datalogistudie til sommer og således formodentligt når igennem det hele over de næste år. Der er jo ikke så meget ved at læse datalogi, hvis man kan halvdelen af programmeringen i forvejen :)
Og nej, jeg har ikke læst artiklen - men det gør jeg nu.

PS: Du kan vist lige så godt smide et svar nu.
Avatar billede Slettet bruger
12. februar 2009 - 00:33 #24
Uha, artiklen trænger godt nok til lidt formatteringsmæssige rettelser - men ellers spændende læsestof. Måske skulle jeg sætte mig bedre ind i bitoperationer, men det bliver ikke i nat... Z'erne er nemlig ved at indhente mig.
Avatar billede arne_v Ekspert
12. februar 2009 - 00:38 #25
Ja - Eksperten V5 har fjernet formateringen som V4 brugte for artikler.
Avatar billede arne_v Ekspert
12. februar 2009 - 00:40 #26
Husk at datalogi ikke er en uddannelse i at programmere.

Du kommer sikkert til at lære en del programmerings sprog - spændende sprog som OCAML, Haskell, Erlang etc..

Men formålet er at lære teori og principper - ikke at kunne alle tricksene i et bestemt sprog.
Avatar billede arne_v Ekspert
12. februar 2009 - 00:41 #27
Og et svar.
Avatar billede Slettet bruger
12. februar 2009 - 00:44 #28
#25
Det tænkte jeg sgu nok.

#26
I know. Jeg vil også foretrække at lære de grundlæggende principper på en uddannelse og selv sætte mig ind i diverse sprog bagefter - hvilket er årsagen til mit fravalg af datamatikeruddannelsen og diverse andre muligheder som alternativer. Så vidt jeg husker, er du selv datalog eller IT-ingeniør...?
Avatar billede arne_v Ekspert
12. februar 2009 - 00:47 #29
Nej - jer er faktisk uddannet økonom (cand.oecon.) for mange mange år siden.
Avatar billede Slettet bruger
12. februar 2009 - 00:51 #30
Nå! Nej, det er sgu ikke ligefrem inden for det datalogiske spektrum :) Jeg må sgu have rodet mine guruer sammen...
Anyway, jeg smutter i seng så godnat herfra.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester



IT-JOB

Cohenware ApS

.NET Backend Developer

Cognizant Technology Solutions Denmark ApS

Sr. Test Analyst

Cognizant Technology Solutions Denmark ApS

Data Architect