Tipo di dati migliore per memorizzare una variabile ternaria o a tre stati


13

Disclaimer: so che i tipi di dati sono un po 'soggettivi rispetto al linguaggio di programmazione / scripting che stai usando, mi piace scrivere in Python come una questione di preferenza; anche se sono felice di conoscere qualsiasi linguaggio / implementazione.

Qual è il miglior tipo di dati per memorizzare una variabile a tre stati? Qualcosa di capace o che rappresenta positivo, neutro e negativo.

Esempio: interi -1, 0, 1.

  • Pro: molto conciso.
  • Pro: potenzialmente efficiente, potrebbe essere memorizzato come un unico numero intero con segno a 2 bit.
  • Pro: potrebbe essere usato come una scala, come un moltiplicatore a virgola mobile.

Esempio 2: 0, null, 1(o qualsiasi permutazione)

  • Pro: il caso d'uso non neutro può essere binario.
  • Contro: richiede un tipo di dati dinamico
  • Contro: potenzialmente non conciso.

Esempio 3: +, (stringa vuota),-

  • Pro: molto conciso.
  • Contro: può utilizzare la logica di stringa per determinare lo stato.
  • Pro ?: Rappresentazione grafica intuitiva.

Forse esiste una logica binaria intelligente che può fare qualcosa di intelligente che non riesco nemmeno a immaginare, forse ci sono troppe considerazioni sul caso d'uso.

Inoltre, ci sono delle considerazioni sull'adattamento di uno stato ternario da archiviare in un motore di database? Come Innodb come riferimento.


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

Ibidem, ma aggiungerei che in molte lingue, i tipi enumerati ti danno molta più sicurezza che provare a inserirli in un altro tipo.
Blrfl,

4
Questa domanda dipende fortemente dal caso d'uso. In generale, tutte le scelte di implementazione elencate sembrano appropriate per scopi diversi, in momenti diversi.
rwong

2
In .NET è possibile utilizzare un valore booleano nullable. La maggior parte dei database ti permetterà di memorizzare un valore booleano (o bit come viene spesso chiamato) con uno stato nullable. È inoltre possibile utilizzare un carattere per l'archiviazione. Il carattere consentirà più spazio in un secondo momento senza dover modificare il meccanismo di archiviazione.
Adam Zuckerman,

1
Un puntatore a bool può anche essere utilizzabile. Bool è forzato a 0 e 1 e se il puntatore è NULL hai il terzo stato. Dipende ovviamente dalla lingua.
Devolus,

Risposte:


7

A parte un enum che è il modo più ovvio e chiaro di esprimerlo, il sistema usato per un sistema interoperabile in cui un enum specifico per una lingua non può essere espresso è l'opzione -1/0/1.

Tuttavia, potresti provare una maschera di bit, dove 0 significa 0, 1 significa "set di bit 2" e 2 significa "set di bit 3" (ovvero hai 3 bit che possono essere attivati ​​o disattivati. Fintanto che non definisci 3, oppure i bit 1 e 2 impostati, allora sei a posto. Questa opzione è la migliore se pensi che potresti aver bisogno di 4 o più flag in futuro, poiché 4, 8, 16 ecc. Imposta i bit successivi).

Tutti questi si inseriscono in un singolo tipo di dati a 8 bit in modo da non sprecare memoria o richiedere la conversione (come farebbe un sistema basato sui caratteri, a volte vengono utilizzati caratteri a 16 bit, a volte a 8 bit a seconda della piattaforma).

Non considererei nulla in ogni caso. Forse in un database, ma solo dove potevo garantire che il sistema avesse un supporto distinto per i NULL, e anche allora potrebbe essere soggetto a errori se qualcuno non facesse esplicitamente la distinzione e finisse con 0 quando era davvero nullo.


La migliore risposta qui IMO. NULL potrebbe essere che semplicemente non è stato aggiunto nel DB, non che il suo stato fosse 'NULL' con -1,0,1 e possibilmente NULL - null indica distintamente che il campo non è mai stato popolato!
Ken,

3

Non intendo scrivere direttamente una risposta chiara a questa domanda; come ho encomiato sopra, questa domanda dipende fortemente dal caso d'uso. In generale, tutte le scelte di implementazione elencate sembrano appropriate per scopi diversi, in momenti diversi.

Tuttavia, vorrei attirare la vostra attenzione su questi principi e conoscenze di base sottostanti, in modo da poter prendere la vostra decisione informata.


Su una nota più leggera, leggi anche questa battuta: "Un uomo d'affari chiede a un commercialista; che cosa sono due più due?"

Ci scusiamo con tutti i ragionieri e non contabili. La mia menzione di questa battuta ha lo scopo di evidenziare la libertà di qualcosa che definiremo molto presto e la responsabilità e le conseguenze (entrambe in senso logico) che ne conseguono.


Domanda: qual è la tabella della verità di una logica a tre valori?

Risposta:

... si alzò dalla sedia, si avvicinò alla porta, la chiuse, tornò e si sedette. Appoggiandosi alla scrivania,

... E tira fuori un diagramma disegnato a mano su un pezzo di carta.

Operazione: logica e - riservata - bozza per Q3 2014

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

... disse a bassa voce, " quanto vorresti che fossero quei valori magici?"

Un designer grafico chiede a un programmatore "Puoi fare un esempio di logica a tre valori?"

Il programmatore risponde: "Puoi darmi due colori, che è bianco e nero come potrebbero essere?"

Graphic designer: "così ... in bianco e nero?"

Programmatore: "esatto. Ora vado a dare un terzo colore, ma dovrò specificarlo come numero ARGB. Spero non ti dispiaccia."

Graphic designer: "bene, lavoro con ARGB ogni giorno ..."

Black#FF000000
White#FFFFFFFF
Nothing#00000000

Osservazione. In quanto sopra, il bianco e nero sono colori completamente opachi. Il terzo colore, Nothing, è completamente trasparente. Se mescolati insieme in vari rapporti, il bianco e nero si mescola per diventare vari grigi, ma mescolare in Nothing non cambia nulla.


Sono abbastanza interessato dall'uso di una tabella della verità, che apre di nuovo gli occhi sul significato dietro le mie stesse domande.
ThorSummoner,

1

Se i tre possibili stati hanno un significato intrinseco, usa qualcosa di adatto a quel significato intrinseco. Ad esempio, i possibili stati sono 1, 2 o 3 oppure, se sono 100, 200 e 300, utilizzare un numero intero. Se i possibili stati sono yes, no o unknown, è possibile utilizzare un booleano facoltativo o un puntatore a un oggetto booleano, con la possibilità di non avere alcun valore, un valore "sì" o un valore "no". Anche se ad alcune persone potrebbe non piacere.

Se esiste un modo ovvio in che modo gli interi possono essere interpretati come possibili stati, è possibile utilizzare l'intero. Dire una funzione di confronto che ha gli stati "meno", "uguale", "maggiore" potrebbe usare -1, 0 e +1. Anche se alcune persone potrebbero non trovare ovvio ciò che trovi ovvio.

Se esiste un modo ovvio per interpretare le lettere come possibili stati, potresti usare un personaggio. Ad esempio, se i tuoi stati sono "rosso", "verde" o "blu", potresti usare le lettere 'r', 'g' e 'b'. Ancora una volta, ciò che è ovvio per te ...

Un tipo elencato è sempre una possibilità. Una stringa è sempre una possibilità, ma perdi il controllo del tipo nella maggior parte delle lingue.

Alcune persone usano tre valori booleani per rappresentare "è nello stato 1", "è nello stato 2", "è nello stato 3".

Qualunque cosa tu faccia, dovresti essere guidato cercando di usare qualcosa che è ovvio e comprensibile, non ti mette nei guai se improvvisamente hai quattro stati e lasciamo che il compilatore trovi gli errori il più possibile.


0

Qual è il miglior tipo di dati per memorizzare una variabile a tre stati? Qualcosa di capace o che rappresenta positivo, neutro e negativo.

Ciò dipende molto dalla lingua, da ciò che stai facendo, dal livello di astrazione (che dipende anche dalla lingua e così via).

Uso principalmente C ++ e ci sono molte scelte qui. Il più semplice è un enum tribool_state { false_val, true_val, undetermined_val }. Ciò sarebbe sufficiente se lo scenario di utilizzo è una singola funzione che restituisce questo tipo di valore.

Probabilmente lo userei boost::optional<bool>se volessi esprimere un risultato booleano che potrebbe essere impossibile ottenere (ad es. Controllare se i dati di rete ricevuti sono completi, quindi elaborare il valore booleano in tal caso).

Vorrei utilizzare boost::triboolse volevo esprimere un risultato booleano sfocata che ha sostenuto tri-state piena logica booleana (ad esempio true || indetermined -> true, false && indetermined -> false, true && indetermined -> indeterminede così via).

Allo stesso modo, in Python, utilizzerei un insieme di costanti o una classe (di nuovo, a seconda del tipo di semantica / operazioni di cui avrei bisogno nel codice client):

Ad esempio, vorrei usare:

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

se avessi un semplice caso di una funzione che restituiva uno dei tre risultati.

Se avessi invece una libreria completa che richiedesse la logica booleana a tre stati, implementerei il tipo di valore come classe.


0

Se si utilizza Java, è possibile utilizzare un oggetto booleano: poiché è un oggetto e contiene un oggetto booleano, può contenere i valori true, false e null. Non sono sicuro se questo sia il modo migliore però.


-6

In Microsoft.NET esiste un tipo "Tuple" che può essere utilizzato per le tue esigenze. Visita http://msdn.microsoft.com/en-us/library/system.tuple%28v=vs.110%29.aspx


Per quella pagina: una tupla è una struttura di dati che ha un numero e una sequenza di elementi specifici. Un esempio di tupla è una struttura di dati con tre elementi (nota come 3-tupla o tripla) che viene utilizzata per memorizzare un identificatore come il nome di una persona nel primo elemento, un anno nel secondo elemento e il reddito della persona per quell'anno nel terzo elemento. .NET Framework supporta direttamente le tuple con uno o sette elementi. Inoltre, puoi creare tuple di otto o più elementi annidando gli oggetti tupla nella proprietà Rest di un oggetto Tuple <T1, T2, T3, T4, T5, T6, T7, TRest>.
Adam Zuckerman,

1
Ciò significa che una tupla può memorizzare qualsiasi tipo fino a un ottuplo (8 dimensioni).
Adam Zuckerman,


Il mio Lang-of-choice, Python, contiene anche un tipo di dati tupla, che un po 'di lettura mi suggerisce, comunque, che le tuple sono appropriate per i dati ternari. O potenzialmente il valore di un indice di tupla sarebbero i dati da archiviare per il caso d'uso e la tupla sarebbe più simile a una costante. Qualcosa sul riferimento a costanti globali, o persino localizzate per indice, mi sembra una cattiva pratica, a meno che tu non sia soggetto a vincoli che proibiscono i lussi.
ThorSummoner,

2
Una tupla è un tipo di dati che può memorizzare più elementi, qualcosa come una struttura, definita solo dinamicamente. Quindi memorizzerebbe 3 variabili del tipo desiderato dall'OP. Non serve a fornire la restrizione sul contenuto che voleva.
gbjbaanb,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.