Trädvy Permalänk
Medlem
Registrerad
Nov 2005

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?

Trädvy Permalänk
Medlem
Plats
Linköping
Registrerad
Jun 2007

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

Trädvy Permalänk
Medlem
Registrerad
Nov 2005

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.

Trädvy Permalänk
Medlem
Registrerad
Dec 2004

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.

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

Trädvy Permalänk
Medlem
Registrerad
Nov 2005

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å...

Trädvy Permalänk
Medlem
Registrerad
Dec 2004

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?

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

Trädvy Permalänk
Medlem
Registrerad
Nov 2005

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

Trädvy Permalänk
Medlem
Plats
Laholm
Registrerad
Okt 2005

sizeof() snälla?

ASP.NET programmerare i C#
Twitter: http://www.twitter.com/hagbarddenstore

Trädvy Permalänk
Medlem
Registrerad
Nov 2005
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.

Trädvy Permalänk
Medlem
Registrerad
Dec 2004
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?

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

Trädvy Permalänk
Medlem
Plats
Umeå
Registrerad
Feb 2004
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

Vill du ha svar? Citera mig gärna.

Trädvy Permalänk
Medlem
Plats
din root :>
Registrerad
Feb 2004
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å?

Trädvy Permalänk
Medlem
Registrerad
Dec 2004
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.

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