Titkok

Titkok

Tanulófeladat

Bevezetés

A bináris számjegyek végső soron közvetlenül a processzorod vagy a memóriád tranzisztorainak felelnek meg: annak, hogy mindegyik „be” vagy „ki” állapotban van-e.

A mély szintű manipuláció, amit köznapi nevén „bit-twiddlingnek” hívnak, különösen fontos a rendszerprogramozási nyelvekben.

A Juliahoz hasonló magas szintű nyelvek azonban általában elfedik ezeknek a részleteknek a nagy részét. A nyelv alapjaiban viszont a bitszintű műveletek teljes skálája elérhető.

Megjegyzés: Ahhoz, hogy a REPL-ben ember által olvasható bináris kimenetet láss, az alábbi példák szinte mindegyikét be kell csomagolni egy bitstring() függvénybe. Ez vizuálisan zavaró, ezért a függvény legtöbb előfordulását kivettem a példákból.

Biteltolási műveletek

Az egész szám típusok, akár előjelesek, akár előjel nélküliek, egyesekből és nullákból álló stringként ábrázolhatók.

julia> bitstring(UInt8(5))
"00000101"

A biteltolás mindössze annyit tesz, hogy mindent balra vagy jobbra mozgat egy megadott számú pozícióval. Az UInt típusoknál néhány bit leesik az egyik végén, a másik végét pedig nullákkal töltjük fel:

julia> ux::UInt8 = 5
5

julia> bitstring(ux)
"00000101"

julia> ux << 2 # left by 2
"00010100"

julia> ux >> 1 # right by 1
"00000010"

Minden balra eltolás megduplázza az értéket, minden jobbra eltolás pedig megfelezi (a csonkolástól függően). Ez tizedes ábrázolásban még szembetűnőbb:

julia> 3 << 2
12

julia> 24 >> 3
3

Ez a fajta biteltolás sokkal gyorsabb, mint a „rendes” aritmetika, ezért ez a technika nagyon népszerű a mély szintű programozásban.

Az előjeles egészeknél egy kicsit óvatosabbnak kell lennünk.

A balra eltolás viszonylag egyszerű:

julia> sx = Int8(5)
5

julia> sx # positive integer
"00000101"

julia> sx << 2
"00010100"

julia> -sx # negative integer
"11111011"

julia> -sx << 2
"11101100"

A pozitív előjeles egészek balra eltolása tehát ugyanaz, mint az előjel nélküli egészeké.

A negatív értékek kettes komplemens formában tárolódnak, ami azt jelenti, hogy a legbaloldalibb bit 1. Balra eltolásnál nincs gond, de jobbra eltolásnál mivel töltjük fel a legbaloldalibb biteket?

julia> sx >> 2 # simple for positive values!
"00000001"

julia> -sx # negative integer
"11111011"

julia> -sx >> 2 # pad with repeated sign bit
"11111110"

julia> -sx >>> 2 # pad with 0
"00111110"

A >> operátor aritmetikai eltolást végez, megőrizve az előjelbitet.

A >>> operátor logikai eltolást végez, nullákkal töltve fel, mintha a szám előjel nélküli lenne.

Bitenkénti logika

Egy korábbi fogalomnál láttuk, hogy a && (és), || (vagy) és ! (nem) operátorokat Boolean értékekkel használjuk.

Vannak ezzel egyenértékű operátorok, a & (bitenkénti és), a | (bitenkénti vagy) és a ~ (tilde, bitenkénti nem), amelyek két egész szám bitjeit hasonlítják össze.

julia> 0b1011 & 0b0010 # bit is 1 in both numbers
"00000010"

julia> 0b1011 | 0b0010 # bit is 1 in at least one number
"00001011"

julia> ~0b1011 # flip all bits
"11110100"

julia> xor(0b1011, 0b0010) # bit is 1 in exactly one number, not both
"00001001"

Itt az xor() a kizáró vagy, függvényként használva.

Utasítások

A barátod épp most küldött neked egy üzenetet egy fontos titokkal. Mivel nem akarta, hogy mások könnyen elolvashassák, az üzenetet bitműveletek sorozatával titkosította. Neked kell megírnod a függvényeket, amelyek segítenek visszafejteni az üzenetet.

1. A bitek visszatolása

Az üzenet visszafejtésének első lépése, hogy a titkosítás során eltolt biteket visszatoljuk jobbra. A visszafejtés további lépései abból indulnak ki, hogy a 0-k a bal oldalról kerülnek be.

Valósítsd meg a shift_back() függvényt, amely egy értéket és az eltolás helyeinek számát kapja, és végrehajtja az eltolást.

shift_back(0b1001, 2) # => 0b0010

2. Néhány bit beállítása

Ezután néhány bitet 1-re kell állítani.

Valósítsd meg a set_bits() függvényt, amely egy értéket és egy maszkot kap, és visszaadja annak eredményét, hogy az érték bitjeit 1-re állítja. Az value bitjét ott kell 1-re állítani, ahol a mask megfelelő bitje is 1. Minden más bit változatlan marad.

set_bits(0b0110, 0b0101) # => 0b0111

3. Bizonyos bitek megfordítása

A titkosítás során bizonyos bitek megfordulnak. Ezeket vissza kell fordítani az üzenet visszafejtéséhez.

Valósítsd meg a flip_bits() függvényt, amely egy értéket és egy maszkot kap. A maszk megmondja, hogy az érték mely bitjeit kell megfordítani. Ahol a mask bitje 1, ott a value megfelelő bitje megfordul. Minden más bit változatlan marad.

flip_bits(0b1100, 0b0101) # => 0b1001

4. Bizonyos bitek 0-ra állítása

Végül vannak olyan bitek is, amelyek mindig 0-ra fejtődnek vissza.

Valósítsd meg a clear_bits() függvényt, amely egy értéket és egy maszkot kap. A value bitjeit ott kell 0-ra állítani, ahol a maszk bitje 1. Minden más bit változatlan marad.

clear_bits(0b0110, 0b0101) # => 0b0010
Szerkesztés GitHubon A hivatkozás új ablakban vagy lapon nyílik meg
Julia Exercism

Készen állsz elkezdeni a(z) Titkok feladatot?

Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) Julia nyelvet 35 fogalom128 feladat segítségével, valódi emberi mentorálással, mindez ingyen.