Springen naar inhoud

Stukje java code.


  • Log in om te kunnen reageren

#1

Bert F

    Bert F


  • >1k berichten
  • 2588 berichten
  • Ervaren gebruiker

Geplaatst op 03 juli 2007 - 16:42

Kan er mij iemand volgend stukje java uitleggen?

// build an int from a byte array - convert little to big endian

public static int constructInt(byte[] in,int offset) {

int ret = ((int)in[offset + 3] & 0xff);

ret = (ret << 8) | ((int)in[offset + 2] & 0xff);

ret = (ret << 8) | ((int)in[offset + 1] & 0xff);

ret = (ret << 8) | ((int)in[offset + 0] & 0xff);

return(ret);

}

Ik heb nog nooit een & gebruikt wel een && en ook nog nooit een | wel || wat bedoelt men met die 0xff is dat gewoon 255?
de int begrijp ik wel (net voor in) dit is om een conversie naar int te forseren.

Maar verder heb ik het raden naar de werking van dit stukje.

Groeten.

Veranderd door Bert F, 03 juli 2007 - 16:43


Dit forum kan gratis blijven vanwege banners als deze. Door te registeren zal de onderstaande banner overigens verdwijnen.

#2

Brinx

    Brinx


  • >1k berichten
  • 1433 berichten
  • Lorentziaan

Geplaatst op 03 juli 2007 - 18:21

Die routine 'bouwt' een integer van een selectie van 4 opeenvolgende bytes uit een array losse bytes die hij aangeleverd krijgt (de 'in[]' array). Hiervoor gebruikt hij onder andere de zogenaamde 'bitwise AND' en de 'bitwise OR': deze operaties vergelijken individuele bits en geven als uitkomst telkens 0 of 1. Eerst een korte uitleg over deze twee operaties:

Bij een bitwise 'AND' operatie (symbool '&') vergelijk je twee bits, en als deze beide '1' zijn is de uitkomst ook '1', anders is de uitkomst '0'. Deze vergelijking kun je ook uitvoeren op hele bit-arrays ('00101010' is een bit-array van 8 elementen, dus een byte) en zo vorm je een nieuwe bit-array die '1'tjes heeft staan op de plaatsen waar beide inputarrays dat ook hebben, en '0' op alle andere plekken.

Een voorbeeld:

01100110 & 11000101 = 01000100

Waarom?

01100110
11000101 &
--------
01000100

Je ziet dat de output-array alleen maar 1'tjes heeft waar beide inputarrays 1'tjes hadden staan.

'Bitwise OR' (symbool '|') is bijna hetzelfde, alleen heeft de output-array nu 1'tjes waar op zijn minst een van beide inputarrays een 1'tje had staan. Gebruiken we de vorige inputarrays nog eens hiervoor, dan krijgen we:

01100110 | 11000101 = 11100111

01100110
11000101 |
--------
11100111

Goed, nu verder naar de routine die je postte. De routine pakt 4 bit-arrays van 8 elementen elk (bytes dus) en 'naait' die aan elkaar tot een grote bit-array van 32 bits: een integer (die dus een grootte heeft van 4 bytes). Die 4 bytes worden achterstevoren achter elkaar gezet (vandaar het 'convert little to big endian: little-endian en big-endian zijn manieren om getallen van meerdere bytes op te slaan, geloof ik: de ene of de andere kant op). Hierbij wordt ook 'bit shifting' gebruikt:

Bijvoorbeeld een bit-shift van het getal 9 (bit-array '00001001'):

00001001 << 4 = 10010000.

Hierbij is de hele serie bits gewoon 4 plaatsen naar links opgeschoven, en zijn de vrijgekomen plaatsen opgevuld met nullen. Omdat iedere bit-shift naar links overeen komt met een vermenigvuldiging van 2, resulteert die bit-shift van net in een getal dat 16 keer zo groot is als 9: namelijk 144 (tel na!).

Een bit-shift van 8 plaatsen naar links, zoals in de code gebeurt, komt dus overeen met het verminigvuldigen van het getal met 256 (2^8). Daarmee wordt dus ruimte gemaakt voor de volgende 8-delige bit-array die ingevoegd wordt - en zo wordt de lange bit-array van 32 elementen opgebouwd uit 4 kortere van 8 elementen elk.

#3


  • Gast

Geplaatst op 04 juli 2007 - 07:45

Wat gaat sneller, bit-shiften of vermenigvuldigen?

#4

Bert F

    Bert F


  • >1k berichten
  • 2588 berichten
  • Ervaren gebruiker

Geplaatst op 04 juli 2007 - 08:01

een beetje verder staat er (niet in dit stukje code) |= is dit een exclusieve of?

#5


  • Gast

Geplaatst op 04 juli 2007 - 12:24

een beetje verder staat er (niet in dit stukje code) |= is dit een exclusieve of?


Bitsgewijs Exclusief Of, xor: ^

#6

Bert F

    Bert F


  • >1k berichten
  • 2588 berichten
  • Ervaren gebruiker

Geplaatst op 04 juli 2007 - 16:56

Merci voor de antwoorden.

Wat gaat sneller, bit-shiften of vermenigvuldigen?


Bedoel je snelheid kwa cpu? geen idee. Denk eerder dat je het gebruik van dat moet zoeken in het al dan niet "handig" omspringen met die zaken, denk niet dat ik dit ooit zelf zou gebruiken.

Groeten.

Veranderd door Bert F, 04 juli 2007 - 16:56


#7


  • Gast

Geplaatst op 04 juli 2007 - 19:05

Bedoel je snelheid kwa cpu? geen idee. Denk eerder dat je het gebruik van dat moet zoeken in het al dan niet "handig" omspringen met die zaken, denk niet dat ik dit ooit zelf zou gebruiken.


Nee, wat betrefd de snelheid van de uitvoering van het programma.

Ik heb eens een keer een klein progje gemaakt wat uuEncode van usenet kon decoderen. Had ik eerst een voorbeeld op internet gezocht, maar de code begreep ik niet, was iets met delen. De uitleg echter wel, in het kort: van 4 bytes moet je 3 bytes maken. Gaat met bit-shifting. Maar je kan dus ook dmv een vermenigvuldiging / deling "bit-shiften".

Een bit-shift van 8 plaatsen naar links, zoals in de code gebeurt, komt dus overeen met het verminigvuldigen van het getal met 256 (2^8).


Zodoende vroeg ik met af wat sneller zou gaan.

#8

Cycloon

    Cycloon


  • >1k berichten
  • 4810 berichten
  • VIP

Geplaatst op 04 juli 2007 - 22:40

Volgens mij is het grote nadeel van bit-shiften dat je enkel met machten van 2 kan vermenigvuldigen (je gaat gewoon de rang van elke waarde gaan verschuiven). Vermenigvuldigen met 3 zit er bv niet in. Zoals Bert F. zei: Het hangt een beetje af van situatie tot situatie.

#9


  • Gast

Geplaatst op 04 juli 2007 - 23:43

Dus een bit shif statement gaat dan net zo snel als een vermenigvuldiging.


Stel ik wil de bits een x-aantal plaatsen naar rechts shiften, ik was eerst aan deling aan het denken.
Maar ik denk dat het ook met vermenigvuldigen kan.

Bijv:
Bits 2 plaatsen naar rechts dmv: waardeByte * (2^ -2), klopt dit?
Dan zou je alleen nog rekening moeten houden met berekeningen die een gebroken getal opleveren.

#10

EvilBro

    EvilBro


  • >5k berichten
  • 6703 berichten
  • VIP

Geplaatst op 05 juli 2007 - 07:38

Dit is niet handig (sterker nog: stom). Je moet geen rare truuks gaan uithalen in je programma's. Je moet gewoon programmeren wat je bedoelt. Dus een 'right shift' doe je met een 'right shift'. Delen door twee doe je met "/2". Pas op het moment dat met een profiler blijkt dat je 'performance issues' hebt, dan pas ga je truuks toepassen.

"We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil." (Code Complete, Page 594)

#11

Cycloon

    Cycloon


  • >1k berichten
  • 4810 berichten
  • VIP

Geplaatst op 05 juli 2007 - 08:57

Bijv:
Bits 2 plaatsen naar rechts dmv: waardeByte * (2^ -2), klopt dit?


Ja klopt.

#12

EvilBro

    EvilBro


  • >5k berichten
  • 6703 berichten
  • VIP

Geplaatst op 05 juli 2007 - 09:50

Ja klopt.

Hoewel het wiskundig gezien hetzelfde is, wil ik toch wel enkele kanttekeningen plaatsen:

2^(-2) is niet een integer. Dat heeft tot gevolg dat of het geheel wordt omgezet naar een double, of de waarde wel in een integer wordt gestopt maar niet een zinnige waarde krijgt. Beide situaties leveren geheid problemen op.

De compiler compileert waarschijnlijk "/2" en ">> 1" naar dezelfde code. Dit is nog een reden om code simpel te houden (dan kan de compiler beter optimaliseren).

#13

Bert F

    Bert F


  • >1k berichten
  • 2588 berichten
  • Ervaren gebruiker

Geplaatst op 05 juli 2007 - 15:11

het grootte verschil is (zie het ook nu pas in) dat je eigenlijk gaat schuiven en niet roteren zo als ik gisteren nog dacht.

dus: we gaan altijd over naar de binaire voorstelling we hebben bv 6 dan zal 0110 in bin.

omdat 8 4 2 1 de "machten" van twee zijn na 1 bitshift hebben we:

1100 zodat 12 volgt.

nog een keer bitshiften oftwel 6 2keer shiften geeft 24 en niet 3 zie je waarom ik dat eerst dacht?

Als je nu files wil uitlezen en je getal te lezen bestaat uit 2 bytes dan heeft die 2de byte meer waarde dan de eerste zie je? dat los je gemakkelijk op met dit shift gedoe.

Groeten.

#14

EvilBro

    EvilBro


  • >5k berichten
  • 6703 berichten
  • VIP

Geplaatst op 05 juli 2007 - 15:20

Ik heb geen idee wat je probeert te zeggen.

#15


  • Gast

Geplaatst op 05 juli 2007 - 15:38

Ik denk dat het verstandiger is om voor een bestand te lezen/schrijven een of andere stream uit de java-api te gebruiken :D





0 gebruiker(s) lezen dit onderwerp

0 leden, 0 bezoekers, 0 anonieme gebruikers

Ook adverteren op onze website? Lees hier meer!

Gesponsorde vacatures

Vacatures