Permalänk
Medlem

Problem med bit shift i C

Hejsan!

Håller på och försöker lära mig lite C. Men har fastnat med bit shift.

int bit = 0; while (...) { ... printf("%d\n", (1 << bit)); bit += 1; }

Denna kod skriver ut 65536 för alla tal bit = [0,...,n]. Enligt vad jag har förstått från min bok och nätet så ska (a << b) == (a * 2^b). Detta borde ju ge [1, 2, 4, 8, 16,...] om jag förstått allt rätt, vilket jag ju uppenbarligen inte gjort Någon som vet vart jag gjort fel?

Permalänk
Medlem

Det där ser ju rätt ut. Är du säker på att den riktiga koden ser ut exakt så där?

Permalänk
Medlem

Yes, hela koden kan du se här. Men det är den biten som är intressant. Det koden ska göra är att hitta hur många bitar de olika variabel-typerna använder. Logiken skulle kunna vara fel, även om jag tror jag har rätt. men det går ju inte att testa fören bit shift fungerar som jag vill.

Kompilera gör jag med följande kommando (på mac) "$ cc -std=c99 -pedantic -Wextra fil.c -o fil" om det skulle göra nån skillnad.

Permalänk
Medlem

Koden körs nog inte riktigt som du hade tänkt.

Så som det är skrivet så skrivs det ut exakt då:

(USHRT_MAX + 1) == 1 << bit

D.v.s. exakt då (1 << bit) är lika med 65535 + 1 = 65536 (precis resultat du får).

I övrigt kan du inte ta reda på bit-storlekarna på det sätt som du har skrivit koden på. I vanliga fall så är "otypade konstanter" per automatik 32-bitars signed heltal. Dina (ULLONG_MAX + 1) och (ULONG_MAX + 1) wrappar högst troligen runt (tänk hexadecimalt: om 0xffffffff är det största 32-bitars unsigned talet, vad händer om vi plussar det med 1? jo, 0!) och (1 << bit) gör det definitivt (höst troligen vid 0x70000000 -> 0x00000000).

Placera printf-satsen utanför if-satsen så ser du vad som händer.

Visa signatur

"Nothing is impossible because impossible itself says I M Possible..."

Permalänk
Medlem

Ahh, i see problemet ligger alltså i att a << b returnerar en 32-bitars heltal, medans jag kanske vill ha upp mot 128 eller nått. Verkar som om jag får låta de små grå jobba lite mer alltså...

Permalänk
Medlem

Tips är att tänka tvärtom. Vad händer om du börjar med en variabel av godtyglig storlek, med alla bittar satta, och sedan shiftar bort dem bittarna en och en?

Visa signatur

"Nothing is impossible because impossible itself says I M Possible..."

Permalänk
Medlem

Låter som en bra aproach Ska testa det! Tack!

Permalänk

sizeof() snälla?

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av hagbarddenstore
sizeof() snälla?

Men då blir det ju för lätt Nä, anledningen var att i boken jag läser hade dom en övningsuppgift där dom ville att man skulle beräkna det på det här sättet, antagligen för att man ska få förståelse för hur bit shift fungerar.

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av kd35a
Men då blir det ju för lätt Nä, anledningen var att i boken jag läser hade dom en övningsuppgift där dom ville att man skulle beräkna det på det här sättet, antagligen för att man ska få förståelse för hur bit shift fungerar.

Plus att sizeof endast ger hur många "chars" som en typ är. Kan du garantera att en char är 8-bitar på alla arkitekturer?

Visa signatur

"Nothing is impossible because impossible itself says I M Possible..."

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av Weeblie
Plus att sizeof endast ger hur många "chars" som en typ är. Kan du garantera att en char är 8-bitar på alla arkitekturer?

sizeof(typ) * CHAR_BIT

Visa signatur

Vill du ha svar? Citera mig gärna.

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av Weeblie
Plus att sizeof endast ger hur många "chars" som en typ är. Kan du garantera att en char är 8-bitar på alla arkitekturer?

Realistiskt sätt, hur många arkitekturer där en char inte är 8-bit kommer detta programmet att stöta på?

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av nystan
Realistiskt sätt, hur många arkitekturer där en char inte är 8-bit kommer detta programmet att stöta på?

Hur många arkitekturer och kompilatorer tror du att detta program kommer att stöta på som inte ger 64-bitars long long, 32-bitars int, 16-bitars short och 8-bitars char? Poängen är inte att om man vet svaret så behöver man bara skriva ut svaret direkt...

I övrigt, om man ställer sig frågan hur många arkitekturer som har char-storlekar på annat än 8-bitar? Tja... rätt så många faktiskt. Även då 7 och 9-bitars chars är väldigt sällsynta så finns det många system som har 16 eller 32-bitars chars.

Visa signatur

"Nothing is impossible because impossible itself says I M Possible..."