Elfhundertelf

Es wäre witzig gewesen, wenn der Eintrag mit diesem Index erst nächsten Mittwoch erschienen wäre. Aber so gut hat’s mit dem Timing halt nicht geklappt.
Vielleicht wird es aber Ende dieses Monats noch einmal passen.

Ich nutze diesen Anlass, hier wieder einmal etwas aus dem Toolkästchen zu plaudern.
Auf Feinheiten und Details werde ich hier bewusst nicht eingehen. Die Programmierer unter meinen Leser kennen das eh, und für die anderen wäre es – in der gebotenen Kürze – nur verwirrend.

Binär wäre ‚1111‘ 8 + 4 + 2 + 1 = 15, also ein hexadezimales F. (BTW hatte ich erst gestern auf Twitter ‚111111111111‘ = 0xFFF Tweets.)

Die Zahl sieht einfach so binär aus, so dass ich zunächst etwas über logische Variablen erzählen möchte.
Eine logische oder Boole’sche Variable gibt an, ob etwas wahr oder falsch ist. Sie steht für die Dichotomie zwischen Ja oder Nein, zwischen 1 oder 0. Eigentlich wird sie durch ein einziges Bit repräsentiert. Ich der Praxis wird jedoch meist ein ganzes Byte (oder gar mehrere) dafür verschwendet.
Boole’sche Variablen erlauben es, im Code mit Hilfe von Abfragen den Programmablauf zu verzweigen. ‚WENN $Variable DANN MACH_DIES, SONST TUE_JENES‘.
Oder sie ermöglichen Wiederholungen: ‚SOLANGE $Variable MACH_DAS‘ bzw. ‚WIEDERHOLE TUE_DIES BIS $Variable‘.
Von einfachen Konstrukten abgesehen, wäre es natürlich witzlos, wenn man mit diesen Variablen nicht auch noch anders umgehen könnte.

So gibt es ein paar logische Operatoren.
‚NICHT $Variable‘ macht aus einer 0 eine 1, und aus einer 1 eine 0.
Zwei Variablen lassen sich verunden, so dass das Ergebnis nur dann 1 ist, wenn beide Variablen 1 sind, ansonsten kommt 0 heraus.
Beim Verodern genügt es, wenn eine der Variablen 1 ist, um 1 zu ergeben. Nur wenn beide gleich 0 sind, erhält man 0 als Resultat.
Interessant ist noch das exklusive Oder, auch als ‚XOR‘ bekannt. Dies liefert eine 1, wenn die Variablen unterschiedlich sind, und eine 0 wenn beide gleich sind.
Schließlich sei noch ‚NAND‘ erwähnt, was einfach eine Negierung der Verundung ist.
Die genannten Verknüpfungen sind alle kommutativ. Es gibt auch nicht-kommutative, etwa die Implikation (die nur dann 0 wird, wenn die erste Variable 1 und die zweite 0 ist).

Kenntnisse der Boole’schen Algebra machen es einfach, Kombinationen dieser Operatoren mit Hilfe der De Morgan’schen Gesetze umzuformen.

Statt die genannten Operatoren nur auf logische Variablen anzuwenden, kann man sie auch bitweise auf integer Variablen loslassen. Beispielsweise ist ’42 UND 10′ gleich 10, da bei beiden Operanden das 8-er und das 2-er Bit gesetzt ist, das 32-er Bit aber nur bei der 42.
Wozu braucht man so etwas? Beispielsweise bei der Bildverarbeitung. RGB etwa stellt jede Farbe als Triple von Bytes pro Farbkanal (Rot, Grün, Blau) dar, eventuell ergänzt durch ein viertes Byte für den Alpha-Kanal. (So lässt sich etwa die Farbe meiner Lieblingssommerbluse darstellen als ARGB=#C0E020E0.) Zum Überblenden oder Ausmaskieren von Bildteilen sind die genannten Operationen nützlich, wenn man sie auf einzelne Pixel anwendet.

Ach, und man kann wunderschön damit herumspielen. Nehmen wir an, wir haben zwei Variablen $X und $Y. Wenn man sie mit dem Gleichheitsoperator vergleicht, kommt 1 heraus, wenn beide identisch sind, und 0 falls sie sich unterscheiden. Behalten wir das mal im Hinterkopf .. äh, Speicher.
Jetzt können wir auch die Differenz $X – $Y bilden. Im Falle der Gleichheit kommt 0 heraus, ansonsten eine Zahl ungleich 0.
Wenn wir nun die Ergebnisse des Gleichheitsoperators und des Differenzoperator verunden, so sind schon mal alle oberen Bits gleich 0, weil durch den logischen Vergleich ja nur das unterste Bit gesetzt ist. Deshalb können wir auch die oberen Bits der Differenz ignorieren. Das unterste Bit der Differenz ist genau dann 1, wenn die Differenz ungerade ist, ansonsten 0.
Verundung bedeutet (wie bereits oben erklärt), dass beide Bits gesetzt sein müssen, damit das Ergebnis „wahr“ ist. Die beiden Zahlen müssten also gleich sein, aber eine ungerade Differenz haben. Das geht nicht, und ist ein Widerspruch. Das heißt, welche Zahlen man auch immer für $X und $Y einsetzt, es kommt immer „falsch“ heraus. Man hätte sich also, hätte man das Problem gründlich durchdacht, die ganze Sache sparen können.
Oder allgemeinverständlich ausgedrückt: Zwei Zahlen können nicht sowohl gleich sein, als auch sich voneinander unterscheiden.

Nicht unerwähnt lassen möchte ich die Schiebeoperatoren, mit denen sich die Bits einer Zahl um eine gegebene Anzahl hin- und herschieben lassen.
Mit Shift-Left schiebt man die Bits nach links (rechts wird mit Nullen aufgefüllt), was einer Multiplikation mit 2 hoch der Anzahl der verschoben Bits entspricht. Entsprechend lässt sich mit Shift-Right durch Zweierpotenzen dividieren (wobei ggf. abgerundet wird).

Abschließend erlaube ich mir noch einen ganz kleinen Schwenk auf die Aussagenlogik (die ich BTW innerhalb einer Philosophie-Vorlesung über Metaphysik hörte).
Wenn die Aussage ‚aus A folgt B‘ wahr ist, welche Rückschlüsse kann man dann daraus ziehen? Folgt dann aus B auch A? Oder folgt aus Nicht-A dann Nicht-B?
Nein. Der einzig gültige Schluss ist ‚aus Nicht-B folgt Nicht-A‘. Leider sind andere Fehlschlüsse weit verbreitet.
Und da ich hier schon gelegentlich notwendige oder hinreichende Bedingungen erwähnt habe: In diesem Beispiel ist A hinreichend für B, und B notwendig für A.
Das alles lässt sich wunderschön mit einem Venn-Diagramm visualisieren.

Und wer jetzt denkt: „Was hat denn die breakpoint heute für einen selbstverständlichen Kram gebloggt?“ – Bedauerlicherweise sind durch solche logischen Zusammenhänge viele Personen intellektuell überfordert. Und zwar nicht diejenigen, die sich jetzt vielleicht – fälschlich – angesprochen fühlen, denn die sind ja zumindest einsichtig und lernfähig. Sondern diejenigen, die sich in Dunning-Kruger-Manier ganz sicher sind, dass sie selbst ja nicht gemeint sein können.
Ob es sich dabei um eine Kausalität oder nur Korrelation handelt, sei dahingestellt.

Advertisements

Über breakpoint AKA Anne Nühm

Die Programmierschlampe.
Dieser Beitrag wurde unter Uncategorized abgelegt und mit , , verschlagwortet. Setze ein Lesezeichen auf den Permalink.

29 Antworten zu Elfhundertelf

  1. aliasnimue schreibt:

    Es ist Samstag morgen und ich hab gerade meinen ersten Kaffee vor mir. Also erlaube ich mir, gleich zum vorletzen Absatz zu springen. für mehr reicht meine Denkfähigkeit nicht aus. 😉

    Gefällt mir

  2. ednong schreibt:

    Also ich kann mich gar nicht angesprochen fühlen, so einfach wie das ist … 😉

    „Ver-und-en“? Ich bitte dich, also wirklich. „Mit UND verknüpfen“ oder „Mit AND verknüpft“ ist da richtig, aber bitte, bitte nicht verunden. Definitiv nicht. Das verhunzt und verödet.

    Gefällt mir

  3. Leser schreibt:

    Das fand ich mal wieder interessant. Ich kann dem folgen, merke aber, dass ich mich an manchen Stellen anstrengen muss (manches habe ich auch einfach akzeptiert, weil mir das Wissen um die Herleitung fehlt, wie etwa dass B notwendig für A sein soll, wenn A hinreichend für B ist).
    Da merke ich mal wieder, dass ich zwar logisch denken *kann* (und ich glaube, dass mir das vor 15 Jahren oder so auch noch viel leichter fiel), aber dass es ebenso auch eine absolute Gewohnheitssache ist, und ich es nicht mehr gewohnt bin, weil es in meinem Alltag in dieser „reinen“, auf die absoluten Grundlagen „herausdestillierten“ Form kaum mehr vorkommt.

    Gefällt mir

    • Oft sind auch Begriffe aus der Mengenlehre anschaulich.
      In diesem Beispiel wäre A eine Teilmenge von B, bzw. B die Obermenge von A.
      Wenn man sich das mal kurz als Venn-Diagramm aufmalt, wird es ganz klar.

      Sicher ist Übung wichtig. Wenn man so etwas dauernd macht, muss man gar nicht mehr richtig bewusst darüber nachdenken, und Logik wird fast zur Intuition.

      Gefällt mir

  4. ZuweiserOderEinweiserOderEinZuWeiser? schreibt:

    Und dann gibt es noch die Nettigkeit mit „=“ versus „==“.
    WENN $A = $B DANN
    (tue Dinge)
    END
    vergleicht nämlich in Sprachen, in denen es „==“ gibt, nicht die Werte von $A und $B, sondern versucht, $A auf den Wert von $B zu setzen, und wenn dies erfolgreich war, wird der Codeblock ausgeführt.
    Kann eine Unachtsamkeit sein, aus der ein Fehler entsteht, kann aber auch ein subtiler Hackversuch sein. Ein solcher Versuch zielte mal auf den Linux-Kernel: http://linux.slashdot.org/story/13/10/09/1551240/the-linux-backdoor-attempt-of-2003

    Abhilfe ist begrenzt möglich, indem man in seinem Coding Styleguide festlegt, dass bei einem Vergleich von Variable und Konstante/Fixwert („Ist $A gleich 42?“) die Konstante/der Fixwert an den Anfang zu setzen ist:
    WENN 42 = $A DANN …
    wird scheitern, da man einer Konstanten/einem fixen Wert keinen anderen Wert zuweisen kann.
    Für Vergleiche zwischen zwei Variablen hilft das natürlich nicht.

    Gefällt mir

  5. Engywuck schreibt:

    TRUE und FALSE als Zahl zu interpretieren ist einfach böse (auch wenns (fast?) alle Programmiersprachen machen). Das führt nur zu blöden Fehlern. Sowas wie „3 < 2 < 1" gibt in manchen Programmiersprachen (Powershell, evtl. C?) "TRUE". Grund: 3 < 2 ist falsch, also 0, und 0 True (-lt für „less than“)
    echo ( $true -eq 1 ) –> True (-eq für „equal“, Boolesche Werte sind als spezielle „Variable“ definiert)
    echo ( 1 + $true ) –> 2
    echo ( $true + 1 ) –> Fehler ‚Der Vorgang „[System.Boolean] + [System.Int32]“ ist nicht definiert.“
    In Vergleichsoperationen wird umgewandelt, in Berechnungen manchmal. Logik dahinter: ??? (Evtl. dass man Skripte aus anderen Sprachen leichter konvertieren kann? Bug-compatible?)

    Ich würde ja noch verstehen, wenn das „0“ und „1“ wäre, weil Boolesche Ringe unterstützt werden, aber dann müsste „*“ als „AND“ und „+“ als „XOR“ gelten.

    Richtig toll wirds dann, wenn TRUE nicht 1 sondern -1 (alle bits gesetzt im Zweierkomplement) oder gar „alles andere als 0“ ist. Viel Spaß mit numerischen Vergleichen…

    Toll ist auch, wenn man Rückgabewerte von Programmen betrachtet: dort ist 0 als „alles OK“ definiert, also quasi „Programm lief NICHT fehlerhaft ab“ (bzw: „ein erfolgreicher Programmlauf ist NICHT auszuschließen“, jeder andere Wert zeigt (meist) einen Fehler an.

    (ja, ich nutze hier die englischen Ausdrücke. Hab zu lange geskriptet :-))

    Gefällt mir

    • Dessen bin ich mir alles bewusst. Ich hatte ja in einem anderen Kommentar typsichere Vergleichsoperatoren erwähnt.

      Da ich selbst hauptsächlich eine streng typisierte Programmiersprache nutze, die solche Konstrukte wie „3 < 2 < 1“ gar nicht erst zulässt, habe ich zumindest eine Fehlerquelle weniger.

      Ich wollte in diesem Eintrag ein wenig beschreiben, was man überhaupt mit logischen oder bitweisen Operatoren machen kann.
      Wer regelmäßig programmiert, kennt die Klippen. Wer nicht, braucht sie nicht zu kennen.

      Als Rückgabewert ist 0 für „succeeded“ besonders geeignet, weil man dann eventuelle Fehlernummern zurückgeben kann, die mehr Information liefern als nur FALSE.
      Dass das Abprüfen auch wieder danebengehen kann .. tja .. Programmieren ist halt nicht so fehlertolerant wie es fertige Anwendungen sein sollten.

      Gefällt mir

  6. Pingback: Dreizehnhundertzwölf | breakpoint

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s