A bináris, az oktális és a hexadecimális (más néven hex) különböző alapú számrendszerek. A bináris 2-es, az oktális 8-as, a hexadecimális 16-os alapú. A Crystalban a közönséges egészek 10-es alapúak. A bináris, az oktális és a hexadecimális mind az egészek reprezentációi. Ez azt jelenti, hogy pozitív és negatív számokat (a nullát is beleértve) ábrázolnak törtek és tizedes törtek nélkül, és minden olyan műveletet támogatnak, amit egészekkel végezhetünk.
A bináris 2-es alapú számrendszer, amely csak a 0 és az 1 számjegyet használja. Általában a számítógépek tranzisztorain és kapcsolóin átfolyó elektromos áram 0 („ki”) és 1 („be”) állapotát ábrázolja, valamint a mágneses tárolóeszközök pozitív és negatív töltéseit. A bináris minden olyan egészet képes ábrázolni, amit a 10-es alapú rendszerben használunk.
A 2-es alapú rendszer egy részlete így néz ki, bár a végtelenségig folytatódik, és nem áll meg 128-nál:
| 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
|---|---|---|---|---|---|---|---|
| 2 ** 7 | 2 ** 6 | 2 ** 5 | 2 ** 4 | 2 ** 3 | 2 ** 2 | 2 ** 1 | 2 ** 0 |
Tehát ha a 6-os számot szeretnénk ábrázolni, az binárisan így néz ki: 110
| Helyiérték | 4 | 2 | 1 |
|---|---|---|---|
| Bináris szám | 1 | 1 | 0 |
A művelet pedig ez lenne: 4 + 2 + 0 = 6
Egy másik példa: 19
| Helyiérték | 16 | 8 | 4 | 2 | 1 |
|---|---|---|---|---|---|
| Bináris szám | 1 | 0 | 0 | 1 | 1 |
A bináris szám ez lenne: 10011
A művelet pedig ez lenne: 16 + 0 + 0 + 2 + 1 = 19
A Crystalban a bináris literálokat a 0b előtaggal ábrázolhatjuk.
Ha leírjuk, hogy 0b10011, a Crystal bináris számként értelmezi, és átváltja 10-es alapra.
0b10011
# => 19
typeof(0b10011)
# => Int32
Ha olyan számot írsz le 0b előtaggal, amely nem a bináris rendszerben van, fordítási hibát kapsz.
0b10211
# => Error: unexpected token: "211"
Mivel a bináris számok egészek, minden olyan műveletet elvégezhetünk rajtuk, amit egészekkel is.
0b10011 + 0b10011
# => 38
0b10011 * 0b10011
# => 361
0b10011 / 3
# => 6.333333333333333
A Crystal a bináris literált automatikusan Int32-vé alakítja.
Ha egy Int32-t bináris reprezentációvá szeretnél alakítani, használd a <int>.to_s(base) metódust úgy, hogy a base argumentum értéke 2 legyen.
A metódus a bináris szám string reprezentációját adja vissza:
19.to_s(2)
# => "10011"
Ha egy bináris szám string reprezentációját egésszé szeretnénk alakítani, használhatjuk a <int>.to_i(base) metódust, átadva a 2-es alapot argumentumként:
"10011".to_i(2)
# => 19
Ha rossz alapot adsz meg (vagy érvénytelen bináris reprezentációt), ArgumentError-t kapsz:
"011021".to_i(2)
# => Invalid Int32: "011021" (ArgumentError)
Vannak bizonyos metódusok, amelyek egészeken használhatók, hogy információt kapjunk a szám bináris reprezentációjáról.
A <int>.bit_length visszaadja, hány bit szükséges a szám ábrázolásához:
19.bit_length
# => 5
A <int>.bit(index) visszaadja az adott indexen lévő bitet, jobbról kezdve (a legkisebb helyiértékű bitet):
19.bit(0)
# => 1
0b10011.bit(1)
# => 1
Az oktális 8-as alapú számrendszer. A 0, 1, 2, 3, 4, 5, 6 és 7 számjegyeket használja.
A Crystalban az oktális számokat a 0o előtaggal ábrázolhatjuk.
A binárishoz hasonlóan a Crystal az oktális reprezentációt automatikusan Int32-vé alakítja.
0o123
# => 83
Ha olyan szám elé írsz 0o-t, amely nem az oktális rendszerben van, fordítási hibát kapsz.
A binárishoz hasonlóan használhatjuk a <int>.to_s(base) metódust, hogy egy Int32-t oktális reprezentációvá alakítsunk.
És a <int>.to_i(base) metódust is használhatjuk, hogy egy oktális reprezentációt Int32-vé alakítsunk.
83.to_s(8)
# => "123"
"123".to_i(8)
# => 83
A binárishoz hasonlóan a rossz alap megadása ArgumentError-t vált ki.
A hexadecimális 16-os alapú számrendszer. A 0 - 9 számjegyeket és az A, B, C, D, E és F betűket használja. Az A 10, a B 11, a C 12, a D 13, az E 14, az F 15.
A hexadecimális számokat a Crystalban a 0x előtaggal ábrázolhatjuk.
A bináris és az oktális rendszerhez hasonlóan a Crystal a hexadecimális literálokat automatikusan Int32-vé alakítja.
#=> 0x123
291
Ha egy nem hexadecimális szám elé 0x-et írsz, fordítási hibát kapsz.
A binárishoz hasonlóan használhatjuk a <int>.to_s(base) metódust, hogy egy Int32-t hexadecimális reprezentációvá alakítsunk.
És a <int>.to_i(base) metódust is használhatjuk, hogy egy hexadecimális reprezentációt Int32-vé alakítsunk.
291.to_s(16)
# => "123"
"123".to_i(16)
# => 291
A bináris és az oktális rendszerhez hasonlóan a rossz alap megadása ArgumentError-t vált ki.
Amikor egy számot string reprezentációvá alakítunk, megadhatjuk a szám pontosságát.
Ez a szám ábrázolásához használt számjegyek minimális mennyiségét jelenti.
Ha a szám kevesebb számjegyből áll, mint a pontosság, akkor a string reprezentáció elejére nullák kerülnek.
Ezt úgy tehetjük meg, hogy átadjuk a precision argumentumot a <int>.to_s(<base>, precision: <value>) metódusnak.
291.to_s(16, precision: 5)
# => "00123"
543.to_s(precision: 2)
# => "543"
A barátod belefáradt abba, hogy fizetnie kell a fotószerkesztő szoftverért, ezért úgy döntött, ír egy sajátot. Az új szoftvernek a Foto Fusionist nevet adta.
A Foto Fusionist egy fotószerkesztő szoftver, ami sok mindenre képes, de eddig ezek közül csak néhányat valósítottál meg. A barátod viszont nagyon örül a haladásnak, és megkért, hogy valósíts meg még néhány funkciót.
A barátod elsőként azt szeretné, hogy a program egy szám bináris ábrázolását egész számmá tudja alakítani. Erre azért van szükség, hogy a szoftver be tudja olvasni egy színcsatorna bináris ábrázolását, és egész számmá alakítsa.
Valósítsd meg a FotoFusionist.binary_to_int metódust, amely egy String típusú binary argumentumot kap.
A metódus a bináris szám egész értékét adja vissza.
FotoFusionist.binary_to_int("10011")
# => 19
A barátod másodikként azt szeretné, hogy egy egész számból ki lehessen keresni a legkisebb helyiértékű bitet. A legkisebb helyiértékű bit a legjobbra eső bit. Azért nevezik legkisebb helyiértékű bitnek, mert neki van a legkisebb értéke.
A legkisebb helyiértékű bitre azért van szükség, hogy meg lehessen állapítani, optimalizálható-e egy kép a színcsatorna ábrázolásához használt bitek számának csökkentésével.
Valósítsd meg a FotoFusionist.least_significant_bit metódust, amely egy Int32 típusú number argumentumot kap.
A metódus adja vissza a szám legkisebb helyiértékű bitjét.
FotoFusionist.least_significant_bit(0b10011)
# => 1
FotoFusionist.least_significant_bit(0b10010)
# => 0
A barátod harmadikként azt szeretné, hogy egy színcsatornából ki lehessen keresni a hexadecimális értéket. A hexadecimális értékre azért van szükség, hogy a színcsatornát hexadecimális ábrázolássá lehessen alakítani, és a kapott hexadecimális ábrázolásnak két számjegyből kell állnia.
Valósítsd meg a FotoFusionist.hex_value metódust, amely egy Int32 típusú number argumentumot kap.
A metódus a szám hexadecimális értékét adja vissza String-ként.
FotoFusionist.hex_value(19)
# => "13"
A barátod negyedikként azt szeretné, hogy egy RGB-színből ki lehessen keresni a hexadecimális értéket. Erre azért van szükség, hogy a felhasználó egyetlen stringként megkapja egy szín ábrázolását. Az RGB-szín olyan szín, amelyet három színcsatorna ábrázol: a vörös, a zöld és a kék. Minden színcsatornát egy 0 és 255 közötti szám ábrázol.
Egy RGB-szín hexadecimális értéke a szín hexadecimális ábrázolása string formájában, ahol először a vörös színcsatorna, aztán a zöld, végül a kék következik.
Valósítsd meg a FotoFusionist.hex_value_from_rgb metódust, amely három argumentumot kap: red, green és blue; mindhárom Int32 típusú.
A metódus az RGB-szín hexadecimális értékét adja vissza String-ként.
FotoFusionist.hex_value_from_rgb(255, 0, 0)
# => "ff0000"
Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) Crystal nyelvet 26 fogalom142 feladat segítségével, valódi emberi mentorálással, mindez ingyen.