Bester Datentyp zum Speichern einer ternären Variablen oder einer Variablen mit drei Zuständen


13

Haftungsausschluss: Ich weiß, dass Datentypen etwas subjektiv für die von Ihnen verwendete Skript- / Programmiersprache sind. Ich schreibe gerne in Python. Ich freue mich jedoch über jede Sprache / Implementierung.

Was ist der beste Datentyp zum Speichern einer Variablen mit drei Zuständen? Etwas, das fähig ist oder Positives, Neutrales und Negatives darstellt.

Beispiel: Die ganzen Zahlen -1, 0, 1.

  • Pro: Sehr prägnant.
  • Pro: Potenziell effizient. Kann als einzelne 2-Bit-Ganzzahl mit Vorzeichen gespeichert werden.
  • Pro: kann als Skala verwendet werden, z. B. als Gleitkomma-Multiplikator.

Beispiel 2: 0, null, 1(oder eine Permutation)

  • Pro: Nicht neutraler Anwendungsfall kann binär sein.
  • Con: Erfordert einen dynamischen Datentyp
  • Con: Möglicherweise nicht prägnant.

Beispiel 3 : +, (leere Zeichenfolge),-

  • Pro: Sehr prägnant.
  • Con: Kann String-Logik verwenden, um den Status zu bestimmen.
  • Pro?: Intuitive grafische Darstellung.

Vielleicht gibt es eine clevere binäre Logik, die etwas Kluges kann, das ich mir gar nicht vorstellen kann. Vielleicht hängt es zu viele Überlegungen zum Anwendungsfall ab.

Gibt es auch Überlegungen bei der Anpassung eines ternären Status zum Speichern in einem Datenbankmodul? Wie Innodb als Referenz.


12
Enum : Python , Java , C # , C , C ++ , go ...

Ibidem, aber ich möchte hinzufügen, dass aufgezählte Typen in vielen Sprachen viel mehr Sicherheit bieten, als wenn Sie versuchen, sie in einen anderen Typ umzuwandeln.
Blrfl

4
Diese Frage hängt stark vom Anwendungsfall ab. Im Allgemeinen scheinen alle aufgelisteten Implementierungsoptionen für unterschiedliche Zwecke zu unterschiedlichen Zeiten geeignet zu sein.
Rwong

2
In .NET können Sie einen nullbaren Booleschen Wert verwenden. In den meisten Datenbanken können Sie einen Booleschen Wert (oder ein Bit, wie es häufig genannt wird) mit einem nullbaren Status speichern. Sie können auch ein Zeichen zur Speicherung verwenden. Der Saibling bietet zu einem späteren Zeitpunkt mehr Platz, ohne dass der Speichermechanismus geändert werden muss.
Adam Zuckerman

1
Ein Zeiger auf bool kann ebenfalls verwendet werden. Bool wird auf 0 und 1 gezwungen und wenn der Zeiger NULL ist, haben Sie den dritten Status. Kommt natürlich auf die Sprache an.
Devolus

Antworten:


7

Abgesehen von einer Aufzählung, die die offensichtlichste und klarste Art ist, dies auszudrücken, ist das System für interoperable Systeme, bei denen eine sprachspezifische Aufzählung nicht ausgedrückt werden kann, die Option -1/0/1.

Sie können jedoch eine Bitmaske ausprobieren, wobei 0 0 bedeutet, 1 "Bit 2 gesetzt" und 2 "Bit 3 gesetzt" bedeutet (dh Sie haben 3 Bits, die ein- oder ausgeschaltet sein können. Solange Sie dies nicht definieren 3 oder Bits 1 und 2 gesetzt, dann sind Sie gut. Diese Option ist am besten geeignet, wenn Sie glauben, dass Sie in Zukunft 4 oder mehr Flags benötigen, da 4, 8, 16 usw. nachfolgende Bits setzen.

All dies passt in einen einzelnen 8-Bit-Datentyp, sodass kein Speicher verschwendet wird oder keine Konvertierung erforderlich ist (wie bei einem zeichenbasierten System werden manchmal 16-Bit-Zeichen verwendet, manchmal 8-Bit-Zeichen, abhängig von Ihrer Plattform).

Ich würde auf keinen Fall null in Betracht ziehen. Vielleicht in einer Datenbank, aber nur dort, wo ich garantieren konnte, dass das System eine eindeutige Unterstützung für NULL-Werte hat, und selbst dann könnte es fehleranfällig sein, wenn jemand die Unterscheidung nicht explizit vornimmt und mit 0 endet, wenn es wirklich null ist.


Die beste Antwort hier IMO. NULL könnte sein, dass es einfach nicht in der Datenbank hinzugefügt wurde, nicht, dass sein Status 'NULL' mit -1,0,1 und möglicherweise NULL war - null zeigt eindeutig an, dass das Feld nie ausgefüllt wurde!
Ken

3

Ich beabsichtige nicht, eine klare Antwort auf diese Frage direkt zu schreiben; Wie ich oben empfohlen habe, hängt diese Frage stark vom Anwendungsfall ab. Im Allgemeinen scheinen alle aufgelisteten Implementierungsoptionen für unterschiedliche Zwecke zu unterschiedlichen Zeiten geeignet zu sein.

Ich möchte Sie jedoch auf diese Grundprinzipien und das Hintergrundwissen aufmerksam machen, damit Sie Ihre eigene fundierte Entscheidung treffen können.


Lesen Sie auch diesen Witz: "Ein Geschäftsmann fragt einen Buchhalter; was ist zwei plus zwei?"

Entschuldigung an alle Buchhalter und Nicht-Buchhalter. Meine Erwähnung dieses Witzes soll die Freiheit von etwas hervorheben, das wir sehr bald definieren werden, und die Verantwortung und die Konsequenzen (beide im logischen Sinne), die sich daraus ergeben.


Frage: Was ist die Wahrheitstabelle einer dreiwertigen Logik?

Antworten:

... stand von seinem Stuhl auf, ging zur Tür, schloss sie, kam zurück und setzte sich. Über den Schreibtisch gelehnt,

... und zieht eine handgezeichnete Karte auf ein Stück Papier.

Betrieb: Logisch und - vertraulich - Entwurf für das dritte Quartal 2014

   FalseTrue Third
FalseFalseFalse?????
True FalseTrue ?????
Third???????????????

... sagte er mit leiser Stimme: " Wie sehr möchten Sie diese magischen Werte haben?"

Ein Grafikdesigner fragt einen Programmierer: "Können Sie ein Beispiel für eine dreiwertige Logik geben?"

Der Programmierer antwortet: "Können Sie mir zwei Farben geben, die so schwarz und weiß sind, wie sie sein könnten?"

Grafikdesigner: "Also ... schwarz und weiß?"

Programmierer: "Genau. Jetzt werde ich eine dritte Farbe geben - aber ich muss sie als ARGB-Nummer angeben. Ich hoffe, es macht Ihnen nichts aus."

Grafikdesigner: "Nun, ich arbeite jeden Tag mit ARGB ..."

Black#FF000000
White#FFFFFFFF
Nothing#00000000

Anmerkung. Oben sind Schwarz und Weiß vollständig undurchsichtige Farben. Die dritte Farbe, Nothing, ist vollständig transparent. Wenn Schwarz und Weiß in verschiedenen Verhältnissen zusammengemischt werden, werden sie zu verschiedenen Grautönen, aber das Einmischen von Nothing ändert nichts.


Ich bin ziemlich interessiert an der Verwendung einer Wahrheitstabelle. Ich öffne wieder meine Augen für die Bedeutung hinter meinen eigenen Fragen.
ThorSummoner

1

Wenn die drei möglichen Zustände eine inhärente Bedeutung haben, verwenden Sie etwas, das für diese inhärente Bedeutung geeignet ist. Beispielsweise sind die möglichen Zustände 1, 2 oder 3, oder wenn sie 100, 200 und 300 sind, verwenden Sie eine Ganzzahl. Wenn die möglichen Zustände Ja, Nein oder Unbekannt sind, können Sie einen optionalen Booleschen Wert oder einen Zeiger auf ein Boolesches Objekt verwenden, mit der Möglichkeit, keinen Wert, einen "Ja" -Wert oder einen "Nein" -Wert zu haben. Obwohl einige Leute es vielleicht nicht mögen.

Wenn es eine offensichtliche Möglichkeit gibt, wie Ganzzahlen als mögliche Zustände interpretiert werden können, können Sie Ganzzahlen verwenden. Angenommen, eine Vergleichsfunktion mit den Zuständen "kleiner", "gleich", "größer" könnte -1, 0 und +1 verwenden. Obwohl einige Leute möglicherweise nicht offensichtlich finden, was Sie offensichtlich finden.

Wenn es eine offensichtliche Möglichkeit gibt, wie Buchstaben als mögliche Zustände interpretiert werden können, können Sie ein Zeichen verwenden. Wenn Ihre Zustände beispielsweise "rot", "grün" oder "blau" sind, können Sie die Buchstaben "r", "g" und "b" verwenden. Wieder, was ist für Sie offensichtlich ...

Ein Aufzählungstyp ist immer eine Möglichkeit. Eine Zeichenfolge ist immer möglich, aber in den meisten Sprachen verlieren Sie die Typprüfung.

Einige Leute verwenden drei boolesche Werte, um "ist in Zustand 1", "ist in Zustand 2", "ist in Zustand 3" darzustellen.

Was auch immer Sie tun, Sie sollten sich von dem Versuch leiten lassen, etwas zu verwenden, das offensichtlich und verständlich ist, Sie nicht in Schwierigkeiten bringt, wenn Sie plötzlich vier Zustände haben, und den Compiler so viele Fehler wie möglich finden lassen.


0

Was ist der beste Datentyp zum Speichern einer Variablen mit drei Zuständen? Etwas, das fähig ist oder Positives, Neutrales und Negatives darstellt.

Dies hängt stark von der Sprache, dem, was Sie tun, der Abstraktionsebene ab (was auch von der Sprache usw. abhängt).

Ich benutze hauptsächlich C ++ und hier gibt es viele Möglichkeiten. Das einfachste ist ein enum tribool_state { false_val, true_val, undetermined_val }. Dies wäre ausreichend, wenn Ihr Verwendungsszenario eine einzelne Funktion ist, die diesen Werttyp zurückgibt.

Ich würde es wahrscheinlich verwenden, boost::optional<bool>wenn ich ein boolesches Ergebnis ausdrücken möchte, das möglicherweise nicht abgerufen werden kann (z. B. prüfen, ob die empfangenen Netzwerkdaten vollständig sind, und dann den booleschen Wert verarbeiten, wenn dies der Fall ist).

Ich würde verwenden , boost::triboolwenn ich ein Fuzzy - boolean Ergebnis , die unterstützte voll Tri-State - Boolesche Logik (zB zum Ausdruck bringen wollte true || indetermined -> true, false && indetermined -> false, true && indetermined -> indeterminedund so weiter).

In ähnlicher Weise würde ich in Python eine Reihe von Konstanten oder eine Klasse verwenden (wiederum abhängig davon, welche Art von Semantik / Operationen ich im Client-Code benötigen würde):

Zum Beispiel würde ich verwenden:

POSITIVE, INDETERMINED, NEGATIVE = 1, 0, -1

Wenn ich einen einfachen Fall hätte, in dem eine Funktion eines von drei Ergebnissen zurückgibt.

Wenn ich stattdessen eine vollständige Bibliothek hätte, die eine boolesche Logik mit drei Zuständen erfordert, würde ich den Werttyp als Klasse implementieren.


0

Wenn Sie Java verwenden, können Sie ein Boolesches Objekt verwenden: Da es sich um ein Objekt handelt und einen Booleschen Wert enthält, kann es die Werte true, false und null enthalten. Ich bin mir nicht sicher, ob dies der beste Weg ist.


-6

In Microsoft.NET gibt es einen Typ "Tupel", der für Ihre Anforderung verwendet werden kann. Besuchen Sie http://msdn.microsoft.com/en-us/library/system.tuple%28v=vs.110%29.aspx


Pro dieser Seite: Ein Tupel ist eine Datenstruktur mit einer bestimmten Anzahl und Folge von Elementen. Ein Beispiel für ein Tupel ist eine Datenstruktur mit drei Elementen (bekannt als 3-Tupel oder Triple), in der eine Kennung wie der Name einer Person im ersten Element, ein Jahr im zweiten Element und das Einkommen der Person gespeichert werden für dieses Jahr im dritten Element. Das .NET Framework unterstützt direkt Tupel mit ein bis sieben Elementen. Darüber hinaus können Sie Tupel mit acht oder mehr Elementen erstellen, indem Sie Tupelobjekte in der Rest-Eigenschaft eines Tupelobjekts <T1, T2, T3, T4, T5, T6, T7, TRest> verschachteln.
Adam Zuckerman

1
Das heißt, ein Tupel kann jeden Typ in bis zu einem Oktupel (8 Dimensionen) speichern.
Adam Zuckerman


Mein Lang-of-Choice, Python, enthält auch einen Tupel-Datentyp, der mir nach einigem Lesen ohnehin nahe legt, dass Tupel für ternäre Daten geeignet sind. Oder möglicherweise ist der Wert eines Tupelindex die Daten, die für den Anwendungsfall gespeichert werden sollen, und das Tupel wäre eher eine Konstante. Etwas über das Referenzieren globaler oder sogar lokalisierter Konstanten nach Index scheint mir eine schlechte Praxis zu sein, es sei denn, Sie stehen unter Einschränkungen, die Luxus verbieten.
ThorSummoner

2
Ein Tupel ist ein Datentyp, der mehrere Elemente speichern kann, beispielsweise eine Struktur, die nur dynamisch definiert ist. Es würden also 3 Variablen des vom OP gewünschten Typs gespeichert. Es dient nicht dazu, den gewünschten Inhalt einzuschränken.
Gbjbaanb
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.