El mejor tipo de datos para almacenar una variable ternaria o de tres estados

13

Descargo de responsabilidad: sé que los tipos de datos son un poco subjetivos para el lenguaje de programación / programación que está utilizando, me gusta escribir en Python como una cuestión de preferencia; aunque me alegra saber de cualquier idioma / implementación.

¿Cuál es el mejor tipo de datos para almacenar una variable de tres estados? Algo capaz o que representa Positivo, Neutro y Negativo.

Ejemplo: Los números enteros -1, 0, 1.

  • Pro: muy conciso.
  • Pro: Potencialmente eficiente, podría almacenarse como un único entero con signo de 2 bits.
  • Pro: podría usarse como una escala, como un multiplicador de coma flotante.

Ejemplo 2: 0, null, 1(o cualquier permutación)

  • Pro: el caso de uso no neutral puede ser binario.
  • Con: Requiere tipo de datos dinámico
  • Con: potencialmente no conciso.

Ejemplo 3: +, (cadena vacía),-

  • Pro: muy conciso.
  • Con: puede utilizar la lógica de cadena para determinar el estado.
  • Pro ?: Representación gráfica intuitiva.

Tal vez hay una lógica binaria inteligente que puede hacer algo inteligente que ni siquiera puedo imaginar, quizás hay demasiadas consideraciones sobre el caso de uso.

Además, ¿hay alguna consideración al adaptar un estado ternario para almacenar en un motor de base de datos? Como Innodb como referencia.

ThorSummoner
fuente
12
Enum : python , java , C # , C , C ++ , go ...
Ibidem, pero agregaría que en muchos idiomas, los tipos enumerados le brindan mucha más seguridad que tratar de calzarlos en otro tipo.
Blrfl
44
Esta pregunta depende en gran medida del caso de uso. En general, todas las opciones de implementación enumeradas parecen apropiadas para algunos propósitos diferentes, en momentos diferentes.
rwong
2
En .NET puede usar un booleano anulable. La mayoría de las bases de datos le permitirán almacenar un booleano (o bit como se le llama a menudo) con un estado anulable. También puede usar un char para el almacenamiento. El char permitirá más espacio en un momento posterior sin tener que cambiar el mecanismo de almacenamiento.
Adam Zuckerman
1
Un puntero a bool también puede ser utilizable. Bool se fuerza a 0 y 1 y si el puntero es NULL tiene el tercer estado. Depende del idioma, por supuesto.
Devolus

Respuestas:

7

Además de una enumeración que es la forma más clara y clara de expresar esto, el sistema utilizado para un sistema interoperable donde no se puede expresar una enumeración específica del idioma es la opción -1/0/1.

Sin embargo, es posible que desee probar una máscara de bits, donde 0 significa 0, 1 significa 'conjunto de bit 2' y 2 significa 'conjunto de bit 3' (es decir, tiene 3 bits que pueden estar activados o desactivados. Siempre y cuando no defina 3, o los bits 1 y 2, entonces está bien. Esta opción es mejor si cree que podría necesitar 4 o más indicadores en el futuro, ya que 4, 8, 16, etc., configuran los bits posteriores).

Todos estos encajan en un solo tipo de datos de 8 bits para que no desperdicie memoria ni requiera conversión (como lo haría un sistema basado en caracteres, a veces se usan caracteres de 16 bits, a veces 8 bits dependiendo de su plataforma).

No consideraría nulo en ningún caso. Tal vez en una base de datos, pero solo donde podría garantizar que el sistema tenía un soporte distinto para NULL, e incluso entonces podría ser propenso a errores si alguien no hizo la distinción explícitamente y terminó con 0 cuando era realmente nulo.

gbjbaanb
fuente
La mejor respuesta aquí IMO. NULL podría ser que simplemente no se agregó en la base de datos, no que su estado era 'NULL' con -1,0,1 y posiblemente NULL: ¡nulo indica claramente que el campo nunca se rellenó!
Ken
3

No tengo la intención de escribir una respuesta clara a esta pregunta directamente; Como recomendé anteriormente, esta pregunta depende en gran medida del caso de uso. En general, todas las opciones de implementación enumeradas parecen apropiadas para algunos propósitos diferentes, en momentos diferentes.

Sin embargo, me gustaría llamar su atención sobre estos principios subyacentes y conocimiento previo, para que pueda tomar su propia decisión informada.


En una nota más ligera, también lea esta broma: "Un hombre de negocios le pregunta a un contador; ¿qué es dos más dos?"

Disculpas a todos los contadores y no contadores. Mi mención de este chiste pretende resaltar la libertad de algo que vamos a definir muy pronto, y la responsabilidad y las consecuencias (ambas en un sentido lógico) que siguen.


Pregunta: ¿cuál es la tabla de verdad de una lógica de tres valores?

Responder:

... se levantó de su silla, se acercó a la puerta, la cerró, volvió y se sentó. Inclinándose sobre el escritorio,

... Y saca un cuadro dibujado a mano en una hoja de papel.

Operación: Lógica y - Confidencial - Borrador para el tercer trimestre de 2014

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

... dijo en voz baja, " ¿cuánto te gustaría que fueran esos valores mágicos?"

Un diseñador gráfico le pregunta a un programador: "¿Puedes dar un ejemplo de lógica de tres valores?"

El programador responde: "¿Puedes darme dos colores, que es tan blanco y negro como podrían ser?"

Diseñador gráfico: "entonces ... ¿blanco y negro?"

Programador: "exactamente. Ahora voy a dar un tercer color, pero tendré que especificarlo como un número ARGB. Espero que no te importe".

Diseñador gráfico: "bueno, trabajo con ARGB todos los días ..."

Black#FF000000
White#FFFFFFFF
Nothing#00000000

Observación. En lo anterior, el blanco y negro son colores totalmente opacos. El tercer color, Nothing, es completamente transparente. Cuando se mezclan en varias proporciones, el blanco y negro se mezcla para convertirse en varios grises, pero mezclar nada no cambia nada.

rwong
fuente
Estoy bastante interesado por el uso de una tabla de verdad. Nuevamente abro los ojos al significado detrás de mis propias preguntas.
ThorSummoner
1

Si los tres estados posibles tienen algún significado inherente, use algo adecuado para ese significado inherente. Por ejemplo, si los estados posibles son 1, 2 o 3, o si son 100, 200 y 300, use un número entero. Si los posibles estados son sí, no o desconocidos, puede usar un booleano opcional o un puntero a un objeto booleano, con la posibilidad de no tener ningún valor, un valor "sí" o un valor "no". Aunque a algunas personas no les guste.

Si hay una manera obvia de cómo los enteros podrían interpretarse como posibles estados, puede usar un entero. Digamos que una función de comparación que tiene estados "menos", "igual", "mayor" podría usar -1, 0 y +1. Aunque algunas personas pueden no encontrar obvio lo que tú encuentras obvio.

Si hay una manera obvia de cómo las letras podrían interpretarse como posibles estados, puede usar un carácter. Por ejemplo, si sus estados son "rojo", "verde" o "azul", puede usar las letras 'r', 'g' y 'b'. De nuevo, lo que es obvio para ti ...

Un tipo enumerado es siempre una posibilidad. Una cadena siempre es una posibilidad, pero pierde la verificación de tipos en la mayoría de los idiomas.

Algunas personas usan tres valores booleanos para representar "está en el estado 1", "está en el estado 2", "está en el estado 3".

Hagas lo que hagas, debes guiarte tratando de usar algo que sea obvio y comprensible, que no te meta en problemas si de repente tienes cuatro estados y que el compilador encuentre los errores tanto como sea posible.

gnasher729
fuente
0

¿Cuál es el mejor tipo de datos para almacenar una variable de tres estados? Algo capaz o que representa Positivo, Neutro y Negativo.

Esto depende en gran medida del idioma, lo que está haciendo, el nivel de abstracción (que también depende del idioma, etc.).

Principalmente uso C ++ y hay muchas opciones aquí. El más simple es un enum tribool_state { false_val, true_val, undetermined_val }. Esto sería suficiente si su escenario de uso es una función única que devuelve este tipo de valor.

Probablemente lo usaría boost::optional<bool>si quisiera expresar un resultado booleano que puede ser imposible de obtener (por ejemplo, verificar si los datos de red recibidos están completos, luego procesar el valor booleano si ese es el caso).

Me gustaría utilizar boost::triboolsi quería expresar un resultado booleano fuzzy que apoyó lógica booleana tri-estado completo (por ejemplo true || indetermined -> true, false && indetermined -> false, true && indetermined -> indeterminedy así sucesivamente).

De manera similar, en Python, usaría un conjunto de constantes o una clase (nuevamente, dependiendo de qué tipo de semántica / operaciones necesitaría en el código del cliente):

Por ejemplo, usaría:

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

si tuviera un caso simple de una función que devuelve uno de los tres resultados.

Si tuviera una biblioteca completa que requiriera una lógica booleana de tres estados, implementaría el tipo de valor como una clase.

utnapistim
fuente
0

Si está utilizando Java, puede usar un objeto booleano: dado que es un objeto y contiene un booleano, puede contener los valores verdadero, falso y nulo. Sin embargo, no estoy seguro de si esta es la mejor manera.

Daniel
fuente
-6

En Microsoft.NET, hay un tipo "Tupla" que se puede usar para sus requisitos. Visite http://msdn.microsoft.com/en-us/library/system.tuple%28v=vs.110%29.aspx

Shadakshari
fuente
Según esa página: una tupla es una estructura de datos que tiene un número específico y una secuencia de elementos. Un ejemplo de una tupla es una estructura de datos con tres elementos (conocidos como 3-tuplas o triples) que se utiliza para almacenar un identificador como el nombre de una persona en el primer elemento, un año en el segundo elemento y los ingresos de la persona. para ese año en el tercer elemento. .NET Framework admite directamente tuplas con uno a siete elementos. Además, puede crear tuplas de ocho o más elementos anidando objetos de tupla en la propiedad Rest de un objeto Tuple <T1, T2, T3, T4, T5, T6, T7, TRest>.
Adam Zuckerman
1
Eso dice que una tupla puede almacenar cualquier tipo en hasta un octuple (8 dimensiones).
Adam Zuckerman
Mi Lang-of-choice, Python, también contiene un tipo de datos de tupla, que un poco de lectura me sugiere, de todos modos, que las tuplas son apropiadas para datos ternarios. O, potencialmente, el valor de un índice de tupla serían los datos a almacenar para el caso de uso y la tupla sería más como una constante. Algo acerca de hacer referencia a constantes globales o incluso localizadas por índice me parece una mala práctica, a menos que tenga restricciones que prohíban los lujos.
ThorSummoner
2
Una tupla es un tipo de datos que puede almacenar múltiples elementos, algo así como una estructura, solo definida dinámicamente. Por lo tanto, almacenaría 3 variables del tipo que el OP quería. No sirve para proporcionar la restricción en el contenido que quería.
gbjbaanb