Meilleur type de données pour stocker une variable ternaire ou à trois états


13

Avertissement: je sais que les types de données sont un peu subjectifs au langage de script / programmation que vous utilisez, j'aime écrire en Python par préférence; bien que je sois heureux d'entendre parler de toute lanugage / implémentation.

Quel est le meilleur type de données pour stocker une variable à trois états? Quelque chose capable ou représentant Positif, Neutre et Négatif.

Exemple: Entiers -1, 0, 1.

  • Pro: Très concis.
  • Pro: potentiellement efficace, pourrait être stocké sous la forme d'un seul entier signé de 2 bits.
  • Pro: pourrait être utilisé comme une échelle, comme un multiplicateur à virgule flottante.

Exemple 2: 0, null, 1(ou toute permutation)

  • Pro: le cas d'utilisation non neutre peut être binaire.
  • Con: nécessite un type de données dynamique
  • Inconvénient: potentiellement pas concis.

Exemple 3: +, (chaîne vide),-

  • Pro: Très concis.
  • Con: Peut utiliser une logique de chaîne pour déterminer l'état.
  • Pro?: Représentation graphique intuitive.

Peut-être qu'il y a une logique binaire intelligente qui peut faire quelque chose d'intelligent que je ne peux même pas imaginer, peut-être qu'il y a trop de considérations sur le cas d'utilisation.

En outre, y a-t-il des considérations lors de l'adaptation d'un état ternaire à stocker dans un moteur de base de données? Comme Innodb pour référence.


12
Enum : python , java , C # , C , C ++ , allez ...

Ibidem, mais j'ajouterais que dans de nombreuses langues, les types énumérés vous offrent beaucoup plus de sécurité que d'essayer de les chausse-pied dans un autre type.
Blrfl

4
Cette question dépend fortement du cas d'utilisation. En général, tous les choix d'implémentation répertoriés semblent appropriés à des fins différentes, à des moments différents.
rwong

2
Dans .NET, vous pouvez utiliser un booléen nullable. La plupart des bases de données vous permettent de stocker un booléen (ou bit comme on l'appelle souvent) avec un état nullable. Vous pouvez également utiliser un caractère pour le stockage. Le char permettra plus d'espace à une date ultérieure sans avoir à changer le mécanisme de stockage.
Adam Zuckerman

1
Un pointeur sur bool peut également être utilisé. Bool est forcé à 0 et 1 et si le pointeur est NULL, vous avez le troisième état. Cela dépend bien sûr de la langue.
Devolus

Réponses:


7

Hormis une énumération qui est la façon la plus évidente et la plus claire de l'exprimer, le système utilisé pour un système interopérable où une énumération spécifique à une langue ne peut pas être exprimée est l'option -1/0/1.

Vous voudrez peut-être essayer un masque de bits, où 0 signifie 0, 1 signifie «bit 2 set» et 2 signifie «bit 3 set» (c'est-à-dire que vous avez 3 bits qui peuvent être activés ou désactivés. Tant que vous ne définissez pas 3, ou les bits 1 et 2 sont définis, alors vous êtes bon. Cette option est préférable si vous pensez que vous pourriez avoir besoin de 4 indicateurs ou plus à l'avenir, car 4, 8, 16, etc. définissent les bits suivants).

Tous ces éléments s'intègrent dans un seul type de données 8 bits afin de ne pas gaspiller de mémoire ni nécessiter de conversion (comme le ferait un système basé sur des caractères, parfois des caractères 16 bits sont utilisés, parfois 8 bits selon votre plate-forme).

Je ne considérerais en aucun cas null. Peut-être dans une base de données, mais seulement là où je pouvais garantir que le système avait un support distinct pour les NULL, et même alors, cela pourrait être sujet à erreur si quelqu'un ne faisait pas explicitement la distinction et se retrouvait avec 0 alors qu'il était vraiment nul.


La meilleure réponse ici IMO. NULL pourrait être simplement qu'il n'a pas été ajouté dans la base de données, pas que son état était 'NULL' avec -1,0,1 et peut-être NULL - null indique distinctement que le champ n'a jamais été rempli!
Ken

3

Je n'ai pas l'intention d'écrire directement une réponse claire à cette question; comme je l'ai recommandé ci-dessus, cette question dépend fortement du cas d'utilisation. En général, tous les choix d'implémentation répertoriés semblent appropriés à des fins différentes, à des moments différents.

Cependant, je voudrais attirer votre attention sur ces principes sous-jacents et connaissances de base, afin que vous puissiez prendre votre propre décision en connaissance de cause.


Sur une note plus légère, lisez également cette blague: "Un homme d'affaires demande à un comptable; qu'est-ce que deux plus deux?"

Toutes mes excuses à tous les comptables et non-comptables. Ma mention de cette blague vise à mettre en évidence la liberté de quelque chose que nous allons définir très bientôt, et la responsabilité et les conséquences (les deux dans un sens logique) qui en découlent.


Question: quelle est la table de vérité d'une logique à trois valeurs?

Réponse:

... se leva de sa chaise, s'approcha de la porte, la referma, revint et s'assit. Se penchant sur le bureau,

... Et sort un tableau dessiné à la main sur un morceau de papier.

Opération: logique et - confidentielle - version préliminaire pour le troisième trimestre 2014

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

... dit-il à voix basse, " combien voudriez-vous que ces valeurs magiques soient?"

Un graphiste demande à un programmeur: "Pouvez-vous donner un exemple de logique à trois valeurs?"

Le programmeur répond: "Pouvez-vous me donner deux couleurs, qui sont aussi noires et blanches qu'elles pourraient l'être?"

Graphiste: "alors ... noir et blanc?"

Programmeur: "exactement. Maintenant, je vais donner une troisième couleur - mais je vais devoir le spécifier comme un numéro ARGB. J'espère que cela ne vous dérange pas."

Graphiste: "eh bien je travaille avec ARGB tous les jours ..."

Black#FF000000
White#FFFFFFFF
Nothing#00000000

Remarque. Dans ce qui précède, le noir et le blanc sont des couleurs entièrement opaques. La troisième couleur, Nothing, est entièrement transparente. Lorsqu'il est mélangé dans différents rapports, le noir et le blanc se mélangent pour devenir des gris variés, mais le mélange dans Nothing ne change rien.


Je suis très intéressé par l'utilisation d'une table de vérité, ouvrant à nouveau les yeux sur le sens de mes propres questions.
ThorSummoner

1

Si les trois états possibles ont une signification inhérente, utilisez quelque chose qui convient à cette signification inhérente. Par exemple, si les états possibles sont 1, 2 ou 3, ou s'ils sont 100, 200 et 300, utilisez un entier. Si les états possibles sont oui, non ou inconnus, vous pouvez utiliser un booléen facultatif ou un pointeur vers un objet booléen, avec la possibilité de n'avoir aucune valeur, une valeur "oui" ou une valeur "non". Bien que certaines personnes ne l'aiment pas.

S'il existe un moyen évident d'interpréter les entiers comme des états possibles, vous pouvez utiliser un entier. Supposons qu'une fonction de comparaison dont les états sont "inférieur", "égal", "supérieur" pourrait utiliser -1, 0 et +1. Bien que certaines personnes ne trouvent pas évident ce que vous trouvez évident.

S'il existe un moyen évident d'interpréter les lettres comme des états possibles, vous pouvez utiliser un caractère. Par exemple, si vos états sont "rouges", "verts" ou "bleus", vous pouvez utiliser les lettres "r", "g" et "b". Encore une fois, ce qui est évident pour vous ...

Un type énuméré est toujours une possibilité. Une chaîne est toujours une possibilité, mais vous perdez la vérification de type dans la plupart des langues.

Certaines personnes utilisent trois valeurs booléennes pour représenter "est dans l'état 1", "est dans l'état 2", "est dans l'état 3".

Quoi que vous fassiez, vous devriez être guidé en essayant d'utiliser quelque chose qui est évident et compréhensible, ne vous cause pas de problèmes si soudainement vous avez quatre états, et laissez le compilateur trouver les erreurs autant que possible.


0

Quel est le meilleur type de données pour stocker une variable à trois états? Quelque chose capable ou représentant Positif, Neutre et Négatif.

Cela dépend beaucoup de la langue, de ce que vous faites, du niveau d'abstraction (qui dépend également de la langue, etc.).

J'utilise principalement C ++ et il y a beaucoup de choix ici. Le plus simple est un enum tribool_state { false_val, true_val, undetermined_val }. Cela serait suffisant si votre scénario d'utilisation est une fonction unique renvoyant ce type de valeur.

J'utiliserais probablement boost::optional<bool>si je voulais exprimer un résultat booléen qui peut être impossible à obtenir (par exemple, vérifier si les données réseau reçues sont complètes, puis traiter la valeur booléenne si c'est le cas).

J'utiliser boost::triboolsi je voulais exprimer un résultat booléen flou qui a soutenu pleinement la logique booléenne tri-état (par exemple true || indetermined -> true, false && indetermined -> false, true && indetermined -> indeterminedetc.).

De même, en python, j'utiliserais un ensemble de constantes ou une classe (encore une fois, selon le type de sémantique / opérations dont j'aurais besoin dans le code client):

Par exemple, j'utiliserais:

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

si j'avais un cas simple d'une fonction renvoyant l'un des trois résultats.

Si j'avais à la place une bibliothèque complète nécessitant une logique booléenne à trois états, j'implémenterais le type de valeur en tant que classe.


0

Si vous utilisez Java, vous pouvez utiliser un objet booléen: puisqu'il s'agit d'un objet et contient un booléen, il peut contenir les valeurs true, false et null. Je ne sais pas si c'est la meilleure façon.


-6

Dans Microsoft.NET, il existe un type "Tuple" qui peut être utilisé selon vos besoins. Visitez http://msdn.microsoft.com/en-us/library/system.tuple%28v=vs.110%29.aspx


Par cette page: Un tuple est une structure de données qui a un nombre et une séquence spécifiques d'éléments. Un exemple de tuple est une structure de données à trois éléments (connue sous le nom de 3-tuple ou triple) qui est utilisée pour stocker un identifiant tel que le nom d'une personne dans le premier élément, une année dans le deuxième élément et le revenu de la personne pour cette année dans le troisième élément. Le .NET Framework prend directement en charge les tuples avec un à sept éléments. De plus, vous pouvez créer des tuples de huit éléments ou plus en imbriquant des objets tuple dans la propriété Rest d'un objet Tuple <T1, T2, T3, T4, T5, T6, T7, TRest>.
Adam Zuckerman

1
Cela signifie qu'un tuple peut stocker n'importe quel type jusqu'à un octuple (8 dimensions).
Adam Zuckerman


Mon Lang-of-choice, Python, contient également un type de données de tuple, qui un peu de lecture suggère, pour moi de toute façon, que les tuples sont appropriés pour les données ternaires. Ou, potentiellement, la valeur d'un index de tuple serait les données à stocker pour le cas d'utilisation et le tuple serait plus comme une constante. Quelque chose au sujet de référencer des constantes globales, voire localisées par index me semble une mauvaise pratique, à moins que vous ne soyez soumis à des contraintes qui interdisent le luxe.
ThorSummoner

2
Un tuple est un type de données qui peut stocker plusieurs éléments, quelque chose comme une structure, uniquement définis dynamiquement. Il stockerait donc 3 variables du type souhaité par l'OP. Cela ne sert pas à fournir la restriction sur le contenu qu'il voulait.
gbjbaanb
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.