Avatar billede casualty Nybegynder
01. juni 2004 - 22:20 Der er 26 kommentarer og
2 løsninger

Hjælp med at shifte og tyde bytes.

Jeg har et problem...
Jeg har 4 bytes...
De skal lægges sammen og det vil give tallet 3492515647.

Jeg ved at de 4 bytes kan give resultatet 3492515647 men jeg får negative tal når jeg lægger dem sammmen...

Kode:
byte[] bytes = new byte[4];
bytes[0]=208;
bytes[1]=43;
bytes[2]=143;
bytes[3]=63;
int sequenzeNumber = (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3];
Console.WriteLine(sequenzeNumber);
Console.ReadLine();

Mvh Casualty
Avatar billede casualty Nybegynder
01. juni 2004 - 22:21 #1
Ovenstående giver -802451649.

Hvad kan det skyldes??
Avatar billede casualty Nybegynder
01. juni 2004 - 22:23 #2
208 = 11010000
43  = 00101011
143 = 10001111
63  = 00111111

Sammensat =  11010000|00101011|10001111|00111111
Uden pipes = 11010000001010111000111100111111
Avatar billede casualty Nybegynder
01. juni 2004 - 22:25 #3
Arne....Hjælp!
Avatar billede rasmusbg Nybegynder
01. juni 2004 - 22:28 #4
Det er på grund af at (11010000 << 24) = 00000000
Da jeg går udfra, at int i C# er et to-komplement binært tal, så bliver det endelige resultat negativt.
Avatar billede casualty Nybegynder
01. juni 2004 - 22:28 #5
Sidder lige og tænker at en int måske er for lille
Avatar billede casualty Nybegynder
01. juni 2004 - 22:29 #6
Hvordan kan det så løses?
Avatar billede rasmusbg Nybegynder
01. juni 2004 - 22:33 #7
Undskyld...tror vist jeg vrøvler. Det er for lag tid siden, jeg har haft teorien omkring to-komplement. Jeg skal lige ha det genopfrisket...
Avatar billede arne_v Ekspert
01. juni 2004 - 22:39 #8
Prøv lige:

int sequenzeNumber = (bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | bytes[0];
Avatar billede rasmusbg Nybegynder
01. juni 2004 - 22:41 #9
En byte er jo kun på 8 bit, og hvis du skifter den 24 pladser til venstre, må den vel blive til 00000000?
Avatar billede casualty Nybegynder
01. juni 2004 - 22:41 #10
Har prøvet... Så giver det 1066347472
Avatar billede arne_v Ekspert
01. juni 2004 - 22:42 #11
byte promotes til int ved shift
Avatar billede casualty Nybegynder
01. juni 2004 - 22:47 #12
Hvorfor giver dette mon det samme?
byte[] bytes = new byte[4];
bytes[0]=208;
bytes[1]=43;
bytes[2]=143;
bytes[3]=63;
int sequenzeNumber = (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3];
int i1 = (bytes[0] << 8) | bytes[1];
int i2 = (i1 << 8) | bytes[2];
int i3 = (i2 << 8) | bytes[3];
Console.WriteLine(i3);
Console.WriteLine(sequenzeNumber);
Console.ReadLine();
Avatar billede arne_v Ekspert
01. juni 2004 - 22:48 #13
uint sequenzeNumber = (uint)((bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]);
Avatar billede casualty Nybegynder
01. juni 2004 - 22:49 #14
Ja det virker... Hvorfor skal den være unsignt? Er det noget med en variabel størrelse?
Avatar billede rasmusbg Nybegynder
01. juni 2004 - 22:50 #15
Arne - Okay.

causalty - Så har jeg haft delvist ret i min første post. Grunden til at det bliver negativt er overflow, og dette er pga. at tallene binært repræsenteres som 2-komplement tal.
Binært er det helt rigtigt udregnet, men kort fortalt, fordi der er et 1-tal på den 32. plads, så bliver det negativt.
Så du skal enten bruge en datatype til resultatet, der bruger mere plads, eller også skal du bruge en unsigned datatype.
Avatar billede jepsen999 Nybegynder
01. juni 2004 - 22:50 #16
Hvis byte promotes til int giver det overflow allerede ved (bytes[3] << 24)
Avatar billede arne_v Ekspert
01. juni 2004 - 22:51 #17
3492515647 kan ikke slet ikke være i en signed int og bliver derfor til -802451649
Avatar billede rasmusbg Nybegynder
01. juni 2004 - 22:53 #18
Jepsen - Nope, (00111111 << 24) = 00111111000000000000000000000000, og det indeholder ikke et 1-tal på 32. plads. Du skal huske int fylder 32 bit.
:o)
Avatar billede arne_v Ekspert
01. juni 2004 - 22:54 #19
I min ordbog kan man ikke tale om overflow ved bit vise operationer - det er et
begreb som jeg kun synes giver mening ved arithmetiske operationer.
Avatar billede arne_v Ekspert
01. juni 2004 - 22:56 #20
og et svar
Avatar billede arne_v Ekspert
01. juni 2004 - 22:57 #21
rasmus>

Det var 208 som blev shiftet op ikke 63 - i spørgsmålet og i svaret der virkede -
jeg foreslog at prøve little endian som shiftede 63 op men det virkede ikke
Avatar billede rasmusbg Nybegynder
01. juni 2004 - 22:58 #22
Arne - Det er selvfølgelig rigtig nok. Men når resultatet skal fortolkes som en int, så ender det jo med overflow.
Avatar billede jepsen999 Nybegynder
01. juni 2004 - 22:58 #23
rasmusbg: det var (byte[3]<< 24) jeg skrev. Altså 11010000 < 24 og det giver overflow :P
Men hvorfor virker det så ikke at caste til en long:
long sequenzeNumber = (long)((bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]);
når arnes trick med uint virker?
Avatar billede arne_v Ekspert
01. juni 2004 - 23:01 #24
Fordi cast fra int til long bevarer den numeriske værdi.

Hvad forventer du ved:

sbyte b = -1;
int i = (int)b;

-1 eller 255 ?
Avatar billede rasmusbg Nybegynder
01. juni 2004 - 23:01 #25
jepsen - I causalty's eksempel er byte[3] = 63...
Avatar billede casualty Nybegynder
01. juni 2004 - 23:03 #26
rasmusbg>> Lægger du ikke også et svar... jeg vil godt give dig 20 af pointene for indsatsen...
Avatar billede jepsen999 Nybegynder
01. juni 2004 - 23:05 #27
ok, jeg har vist fået rodet lidt rundt i mit lille kodeeksempel, - og er vist I øvrigt nået ud i den del af den bitwise-verden hvor jeg ikke kan bunde...
pas!
;)
Avatar billede rasmusbg Nybegynder
01. juni 2004 - 23:07 #28
Svar :o)
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
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

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