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.
fuente
Respuestas:
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.
fuente
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:
... 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???????????????
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.
fuente
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.
fuente
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::tribool
si quería expresar un resultado booleano fuzzy que apoyó lógica booleana tri-estado completo (por ejemplotrue || indetermined -> true
,false && indetermined -> false
,true && indetermined -> indetermined
y 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:
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.
fuente
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.
fuente
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
fuente