Melhor tipo de dados para armazenar uma variável ternária ou de três estados

13

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.

ThorSummoner
fonte
12
Enum : python , java , C # , C , C ++ , go ...
Ibidem, mas eu acrescentaria que em muitos idiomas, os tipos enumerados oferecem muito mais segurança do que tentar calçá-los em algum outro tipo.
Blrfl
4
Esta 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.
Rjong
2
No .NET, você pode usar um booleano anulável. A maioria dos bancos de dados permitirá que você armazene um booleano (ou bit, como costuma ser chamado) com um estado anulável. Você também pode usar um caractere para armazenamento. O char permitirá mais espaço posteriormente, sem precisar alterar o mecanismo de armazenamento.
Adam Zuckerman
1
Um ponteiro para bool também pode ser utilizável. Bool é forçado a 0 e 1 e se o ponteiro for NULL, você terá o terceiro estado. Depende do idioma, é claro.
Devolus

Respostas:

7

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.

gbjbaanb
fonte
A melhor resposta aqui IMO. NULL pode ser que ele simplesmente não foi adicionado ao banco de dados, não que seu estado fosse 'NULL' com -1,0,1 e possivelmente NULL - null - indica claramente que o campo nunca foi preenchido!
Ken
3

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:

... levantou-se da cadeira, foi até a porta, fechou-a, voltou e sentou-se. Inclinando-se sobre a mesa,

... 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???????????????

... ele disse em voz baixa: " Quanto você gostaria que esses valores mágicos fossem?"

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.

rwong
fonte
Estou bastante interessado no uso de uma tabela da verdade, abrindo novamente meus olhos para o significado por trás de minhas próprias perguntas.
ThorSummoner
1

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.

gnasher729
fonte
0

Qual é o melhor tipo de dados para armazenar uma variável de três estados? Algo capaz ou representando positivo, neutro e negativo.

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::triboolse eu queria expressar um resultado boolean difusa que apoiou lógica booleana tri-state completo (por exemplo true || indetermined -> true, false && indetermined -> false, true && indetermined -> indeterminede 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:

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

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.

utnapistim
fonte
0

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.

Daniel
fonte
-6

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

Shadakshari
fonte
Por essa página: uma tupla é uma estrutura de dados que possui um número e uma sequência específicos de elementos. Um exemplo de uma tupla é uma estrutura de dados com três elementos (conhecidos como três ou triplos) que são usados ​​para armazenar um identificador como o nome de uma pessoa no primeiro elemento, um ano no segundo elemento e a renda da pessoa para esse ano no terceiro elemento. O .NET Framework suporta diretamente tuplas com um a sete elementos. Além disso, você pode criar tuplas de oito ou mais elementos, aninhando objetos de tupla na propriedade Rest de um objeto Tupla <T1, T2, T3, T4, T5, T6, T7, TRest>.
Adam Zuckerman
1
Isso indica que uma tupla pode armazenar qualquer tipo em um octuplo (8 dimensões).
Adam Zuckerman
Meu Lang de escolha, Python, também contém um tipo de dados de tupla, que um pouco de leitura sugere, para mim, que as tuplas são apropriadas para dados ternários. Ou, potencialmente, o valor de um índice de tupla seria os dados a serem armazenados para o caso de uso e a tupla seria mais como uma constante. Algo sobre referenciar constantes globais ou mesmo localizadas por índice parece uma prática ruim para mim, a menos que você esteja sob restrições que proíbem luxos.
ThorSummoner
2
Uma tupla é um tipo de dados que pode armazenar vários elementos, algo como uma estrutura, apenas definida dinamicamente. Portanto, ele armazenaria três variáveis ​​do tipo que o OP queria. Não serve para fornecer a restrição de conteúdo que ele queria.
Gbjbaanb