Tracks
/
Crystal
Crystal
/
Übungen
/
Foto-Fusionist
Foto-Fusionist

Foto-Fusionist

Lernübung

Einführung

Binär, Oktal und Hexadezimal (auch Hex genannt) sind verschiedene Zahlensysteme mit unterschiedlichen Basen. Binär hat die Basis 2, Oktal die Basis 8 und Hexadezimal die Basis 16. Normale Ganzzahlen haben in Crystal die Basis 10. Binär, Oktal und Hexadezimal sind alles Darstellungen von Ganzzahlen. Das bedeutet, dass sie positive und negative Zahlen (einschließlich null) ohne Brüche oder Dezimalstellen darstellen und alle Operationen unterstützen, die wir mit Ganzzahlen ausführen können.

Binär

Binär ist ein Zahlensystem zur Basis 2, das nur die Ziffern 0 und 1 verwendet. Es stellt üblicherweise die Zustände 0 („aus“) und 1 („an“) des elektrischen Flusses durch Transistoren und Schalter in Computern dar, ebenso wie die positiven und negativen Ladungen in magnetischen Speichermedien. Binär kann alle Ganzzahlen darstellen, die in der Basis 10 verwendet werden.

Ein Ausschnitt aus dem System zur Basis 2 sieht so aus, obwohl es unendlich weitergeht und nicht bei 128 endet:

128 64 32 16 8 4 2 1
2 ** 7 2 ** 6 2 ** 5 2 ** 4 2 ** 3 2 ** 2 2 ** 1 2 ** 0

Wenn wir also die Zahl 6 darstellen wollen, wäre das in Binär: 110

Stellenwert 4 2 1
Binärzahl 1 1 0

Und die Rechnung wäre: 4 + 2 + 0 = 6

Ein weiteres Beispiel: 19

Stellenwert 16 8 4 2 1
Binärzahl 1 0 0 1 1

Die Binärzahl wäre: 10011 Und die Rechnung wäre: 16 + 0 + 0 + 2 + 1 = 19

Binär in Crystal

In Crystal können wir Binärliterale mit dem Präfix 0b darstellen. Wenn wir 0b10011 schreiben, interpretiert Crystal das als Binärzahl und wandelt sie in die Basis 10 um.

0b10011
# => 19

typeof(0b10011)
# => Int32

Wenn du eine Zahl mit dem Präfix 0b schreibst, die nicht im Binärsystem ist, führt das zu einem Kompilierungsfehler.

0b10211
# => Error: unexpected token: "211"

Rechnen mit Binärzahlen

Da Binärzahlen Ganzzahlen sind, können wir alle Operationen mit ihnen ausführen, die wir mit Ganzzahlen ausführen können.

0b10011 + 0b10011
# => 38

0b10011 * 0b10011
# => 361

0b10011 / 3
# => 6.333333333333333

Umwandlung in und aus der Binärdarstellung

Crystal wandelt ein Binärliteral automatisch in Int32 um. Um einen Int32 in eine Binärdarstellung umzuwandeln, verwendest du die Methode <int>.to_s(base) mit dem Basis-Argument 2. Die Methode gibt eine String-Darstellung der Binärzahl zurück:

19.to_s(2)
# => "10011"

Um eine String-Darstellung einer Binärzahl in eine Ganzzahl umzuwandeln, können wir die Methode <int>.to_i(base) verwenden und die Basis (2) als Argument übergeben:

"10011".to_i(2)
# => 19

Eine falsche Basis (oder eine ungültige Binärdarstellung) führt zu einem ArgumentError:

"011021".to_i(2)
# => Invalid Int32: "011021" (ArgumentError)

Binäre Methoden

Es gibt bestimmte Methoden, die auf Ganzzahlen angewendet werden können, um Informationen über die Binärdarstellung der Zahl zu erhalten.

<int>.bit_length gibt die Anzahl der Bits zurück, die benötigt werden, um die Zahl darzustellen:

19.bit_length
# => 5

<int>.bit(index) gibt das Bit am angegebenen Index zurück, von rechts gezählt (niedrigstwertiges Bit):

19.bit(0)
# => 1

0b10011.bit(1)
# => 1

Oktal

Oktal ist ein Zahlensystem zur Basis 8. Es verwendet die Ziffern 0, 1, 2, 3, 4, 5, 6 und 7.

In Crystal können wir Oktalzahlen mit dem Präfix 0o darstellen. Wie bei Binär wandelt Crystal eine Oktaldarstellung automatisch in einen Int32 um.

0o123
# => 83

Wenn du einer Zahl das Präfix 0o voranstellst, die nicht im Oktalsystem ist, führt das zu einem Kompilierungsfehler.

Umwandlung in und aus der Oktaldarstellung

Wie bei Binär können wir die Methode <int>.to_s(base) verwenden, um einen Int32 in eine Oktaldarstellung umzuwandeln. Und wir können die Methode <int>.to_i(base) verwenden, um eine Oktaldarstellung in einen Int32 umzuwandeln.

83.to_s(8)
# => "123"

"123".to_i(8)
# => 83

Wie bei Binär führt eine falsche Basis zu einem ArgumentError.

Hexadezimal

Hexadezimal ist ein Zahlensystem zur Basis 16. Es verwendet die Ziffern 0 - 9 und die Buchstaben A, B, C, D, E und F. A steht für 10, B für 11, C für 12, D für 13, E für 14 und F für 15.

In Crystal können wir Hexadezimalzahlen mit dem Präfix 0x darstellen. Wie bei Binär und Oktal wandelt Crystal Hexadezimalliterale automatisch in Int32 um.

#=> 0x123
291

Wenn du einer Nicht-Hexadezimalzahl das Präfix 0x voranstellst, führt das zu einem Kompilierungsfehler.

Umwandlung in und aus der Hexadezimaldarstellung

Wie bei Binär können wir die Methode <int>.to_s(base) verwenden, um einen Int32 in eine Hexadezimaldarstellung umzuwandeln. Und wir können die Methode <int>.to_i(base) verwenden, um eine Hexadezimaldarstellung in einen Int32 umzuwandeln.

291.to_s(16)
# => "123"

"123".to_i(16)
# => 291

Wie bei Binär und Oktal führt eine falsche Basis zu einem ArgumentError.

Genauigkeit

Wenn wir eine Zahl in eine String-Darstellung umwandeln, können wir die Genauigkeit der Zahl angeben. Das bedeutet die minimale Anzahl an Ziffern, die zur Darstellung der Zahl verwendet wird. Hat die Zahl weniger Ziffern als die Genauigkeit, werden führende Nullen an die String-Darstellung angehängt. Dazu übergibst du das Argument precision an die Methode <int>.to_s(<base>, precision: <value>).

291.to_s(16, precision: 5)
# => "00123"

543.to_s(precision: 2)
# => "543"

Anleitung

Dein Freund hat es satt, für Fotobearbeitungssoftware zu bezahlen, und beschlossen, seine eigene zu schreiben. Dein Freund hat entschieden, die neue Software Foto Fusionist zu nennen.

Foto Fusionist ist eine Fotobearbeitungssoftware, die eine Menge Dinge kann, aber du hast bisher nur wenige davon implementiert. Trotzdem ist dein Freund mit den Fortschritten sehr zufrieden und hat dich gebeten, noch ein paar weitere Funktionen zu implementieren.

1. Binärdarstellung in eine Ganzzahl umwandeln

Für die erste Funktion möchte dein Freund in der Lage sein, eine Binärdarstellung einer Zahl in eine Ganzzahl umzuwandeln. Das ist nötig, weil die Software die Binärdarstellung eines Farbkanals lesen und in eine Ganzzahl umwandeln können soll.

Implementiere die Methode FotoFusionist.binary_to_int, die ein Argument binary vom Typ String entgegennimmt. Die Methode sollte die Ganzzahldarstellung der Binärzahl zurückgeben.

FotoFusionist.binary_to_int("10011")
# => 19

2. Niedrigstwertiges Bit aus einer Ganzzahl ermitteln

Die zweite Funktion, die dein Freund möchte, ist, das niedrigstwertige Bit aus einer Ganzzahl ermitteln zu können. Das niedrigstwertige Bit ist das Bit, das am weitesten rechts steht. Es heißt niedrigstwertiges Bit, weil es den geringsten Wert hat.

Das niedrigstwertige Bit wird benötigt, um zu beurteilen, ob ein Bild optimiert werden kann, indem die Anzahl der Bits reduziert wird, die zur Darstellung des Farbkanals verwendet werden.

Implementiere die Methode FotoFusionist.least_significant_bit, die ein Argument number vom Typ Int32 entgegennimmt. Die Methode sollte das niedrigstwertige Bit der Zahl zurückgeben.

FotoFusionist.least_significant_bit(0b10011)
# => 1

FotoFusionist.least_significant_bit(0b10010)
# => 0

3. Hex-Wert aus einem Farbkanal ermitteln

Die dritte Funktion, die dein Freund möchte, ist, den Hex-Wert aus einem Farbkanal ermitteln zu können. Der Hex-Wert wird benötigt, um den Farbkanal in eine Hex-Darstellung umzuwandeln, und die gegebene Hex-Darstellung muss aus zwei Ziffern bestehen.

Implementiere die Methode FotoFusionist.hex_value, die ein Argument number vom Typ Int32 entgegennimmt. Die Methode sollte den Hex-Wert der Zahl als String zurückgeben.

FotoFusionist.hex_value(19)
# => "13"

4. Hex-Wert aus RGB ermitteln

Die vierte Funktion, die dein Freund möchte, ist, den Hex-Wert aus einer RGB-Farbe ermitteln zu können. Das ist nötig, damit ein Benutzer eine einzelne String-Darstellung einer Farbe erhalten kann. Eine RGB-Farbe ist eine Farbe, die durch drei Farbkanäle dargestellt wird: Rot, Grün und Blau. Jeder Farbkanal wird durch eine Zahl zwischen 0 und 255 dargestellt.

Der Hex-Wert einer RGB-Farbe ist eine String-Darstellung der Farbe im Hexadezimalsystem, wobei der rote Farbkanal zuerst kommt, dann der grüne Farbkanal und zuletzt der blaue Farbkanal.

Implementiere die Methode FotoFusionist.hex_value_from_rgb, die drei Argumente entgegennimmt: red, green und blue vom Typ Int32. Die Methode sollte den Hex-Wert der RGB-Farbe als String zurückgeben.

FotoFusionist.hex_value_from_rgb(255, 0, 0)
# => "ff0000"
Über GitHub bearbeiten Der Link öffnet sich in einem neuen Fenster oder Tab
Crystal Exercism

Bereit, mit Foto-Fusionist zu starten?

Melde dich bei Exercism an, um Crystal mit 26 Konzepte142 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.