Isenção de responsabilidade: eu sei que os tipos de dados são um pouco subjetivos para qual linguagem de script / programação você está usando, eu gosto de escrever em Python como uma questão de preferência; embora esteja feliz em saber sobre qualquer linguagem / implementação.
Qual é o melhor tipo de dados para armazenar uma variável de três estados? Algo capaz ou representando positivo, neutro e negativo.
Exemplo: Inteiros -1
, 0
, 1
.
- Pro: muito conciso.
- Pro: potencialmente eficiente, pode ser armazenado como um único inteiro assinado de 2 bits.
- Pro: pode ser usado como uma escala, como um multiplicador de ponto flutuante.
Exemplo 2: 0
, null
, 1
(ou qualquer permutação)
- Pro: caso de uso não neutro pode ser binário.
- Con: Requer tipo de dados dinâmico
- Con: Potencialmente não conciso.
Exemplo 3: +
, (cadeia vazia),
-
- Pro: muito conciso.
- Con: Pode utilizar lógica de cadeia para determinar o estado.
- Pro ?: Representação gráfica intuitiva.
Talvez exista alguma lógica binária inteligente que possa fazer algo inteligente que eu nem consigo imaginar; talvez exista muitas considerações sobre o caso de uso.
Além disso, existem considerações ao adaptar um estado ternário para armazenar em um mecanismo de banco de dados? Como Innodb para referência.
fonte
Respostas:
Além de uma enumeração que é a maneira mais clara e óbvia de expressar isso, o sistema usado para sistemas interoperáveis onde uma enumer específica de idioma não pode ser expressa é a opção -1/0/1.
Você pode tentar uma máscara de bits, onde 0 significa 0, 1 significa 'bit 2 set' e 2 significa 'bit 3 set' (ou seja, você tem 3 bits que podem ser ativados ou desativados. Contanto que você não defina 3 ou bits 1 e 2., então você é bom.Esta opção é melhor se você acha que poderá precisar de 4 ou mais sinalizadores no futuro, pois 4, 8, 16 etc. define os bits subsequentes).
Tudo isso se encaixa em um único tipo de dados de 8 bits, para que não desperdice memória ou exija conversão (como um sistema baseado em caracteres faria, algumas vezes caracteres de 16 bits são usados, outras vezes, 8 bits dependendo da sua plataforma).
Eu não consideraria nulo em nenhum caso. Talvez em um banco de dados, mas apenas onde eu pudesse garantir que o sistema tivesse suporte distinto para NULLs, e mesmo assim poderia ser propenso a erros se alguém não fizesse a distinção explicitamente e terminasse com 0 quando realmente fosse nulo.
fonte
Não pretendo escrever uma resposta clara a esta pergunta diretamente; como eu recomendei acima, essa pergunta é altamente dependente do caso de uso. Em geral, todas as opções de implementação listadas parecem apropriadas para finalidades diferentes, em momentos diferentes.
No entanto, gostaria de chamar sua atenção para esses princípios e conhecimentos básicos, para que você possa tomar sua própria decisão informada.
Em uma nota mais clara, leia também a piada: "Um empresário pergunta a um contador; o que são dois mais dois?"
Desculpas a todos os contadores e não contadores. Minha menção a essa piada tem como objetivo destacar a liberdade de algo que definiremos muito em breve, e a responsabilidade e as consequências (ambas em sentido lógico) a seguir.
Pergunta: qual é a tabela da verdade de uma lógica de três valores?
Responda:
... E puxa um gráfico desenhado à mão em um pedaço de papel.
Operação: Lógico E - Confidencial - Rascunho para o terceiro trimestre de 2014
FalseTrue Third
FalseFalseFalse?????
True FalseTrue ?????
Third???????????????
Um designer gráfico pergunta a um programador: "Você pode dar um exemplo de lógica com três valores?"
O programador responde: "Você pode me dar duas cores, o mais preto e branco possível?"
Designer gráfico: "então ... preto e branco?"
Programador: "exatamente. Agora vou dar uma terceira cor - mas vou precisar especificá-la como um número ARGB. Espero que você não se importe."
Designer gráfico: "bem, eu trabalho com o ARGB todos os dias ..."
Black#FF000000
White#FFFFFFFF
Nothing#00000000
Observação. Acima, preto e branco são cores totalmente opacas. A terceira cor, Nothing, é totalmente transparente. Quando misturados em várias proporções, preto e branco se mistura para se tornar vários tons de cinza, mas a mistura em Nothing não muda nada.
fonte
Se os três estados possíveis tiverem algum significado inerente, use algo adequado para esse significado inerente. Por exemplo, os estados possíveis são 1, 2 ou 3 ou, se forem 100, 200 e 300, use um número inteiro. Se os possíveis estados forem sim, não ou desconhecido, você poderá usar um booleano opcional ou um ponteiro para um objeto booleano, com a possibilidade de não ter valor, valor "sim" ou valor "não". Embora algumas pessoas possam não gostar.
Se houver uma maneira óbvia de como os números inteiros podem ser interpretados como possíveis estados, você poderá usar o número inteiro. Digamos que uma função de comparação que possua estados "menos", "igual", "maior" possa usar -1, 0 e +1. Embora algumas pessoas possam não achar óbvio o que você acha óbvio.
Se houver uma maneira óbvia de como as letras podem ser interpretadas como possíveis estados, você pode usar um caractere. Por exemplo, se seus estados são "vermelho", "verde" ou "azul", você pode usar as letras 'r', 'g' e 'b'. Novamente, o que é óbvio para você ...
Um tipo enumerado é sempre uma possibilidade. Uma string é sempre uma possibilidade, mas você perde a verificação de tipo na maioria dos idiomas.
Algumas pessoas usam três valores booleanos para representar "está no estado 1", "está no estado 2", "está no estado 3".
Seja o que for que você faça, você deve ser orientado tentando usar algo óbvio e compreensível, que não cause problemas se, de repente, você tiver quatro estados, e que o compilador encontre os erros o máximo possível.
fonte
Isso depende muito do idioma, do que você está fazendo, do nível de abstração (que também depende do idioma e assim por diante).
Eu uso principalmente C ++ e há muitas opções aqui. O mais simples é um
enum tribool_state { false_val, true_val, undetermined_val }
. Isso seria suficiente se o cenário de uso for uma única função retornando esse tipo de valor.Eu provavelmente usaria
boost::optional<bool>
se quisesse expressar um resultado booleano que pode ser impossível de obter (por exemplo, verifique se os dados de rede recebidos estão completos e processe o valor booleano, se for esse o caso).Eu usaria
boost::tribool
se eu queria expressar um resultado boolean difusa que apoiou lógica booleana tri-state completo (por exemplotrue || indetermined -> true
,false && indetermined -> false
,true && indetermined -> indetermined
e assim por diante).Da mesma forma, em python, eu usaria um conjunto de constantes ou uma classe (novamente, dependendo de que tipo de semântica / operações eu precisaria no código do cliente):
Por exemplo, eu usaria:
se eu tivesse um caso simples de uma função retornando um dos três resultados.
Se eu tivesse uma biblioteca completa exigindo lógica booleana de três estados, implementaria o tipo de valor como uma classe.
fonte
Se você estiver usando Java, poderá usar um objeto booleano: como é um objeto e contém um booleano, ele pode reter os valores true, false e null. Não tenho certeza se essa é a melhor maneira.
fonte
No Microsoft.NET, existe um tipo "Tupla" que pode ser usado para sua exigência. Visite http://msdn.microsoft.com/en-us/library/system.tuple%28v=vs.110%29.aspx
fonte