10

Disclaimer: I know that datatypes are a little bit subjective to which scripting/programming language you are using, I like to write in Python as a matter of preference; though I am happy to hear about any lanugage/implementation.

What is the best datatype to store a three-state variable? Something capable or representing Positive, Neutral, and Negative.

Example: Integers -1, 0, 1.

  • Pro: Very concise.
  • Pro: Potentially efficient, Could be stored as a single 2-bit signed integer.
  • Pro: could be used as a scale, such as a floating point multiplier.

Example 2: 0, null, 1 (or any permutation)

  • Pro: Non-neutral use case can be binary.
  • Con: Requires dynamic datatype
  • Con: Potentially not concise.

Example 3: +, (empty string), -

  • Pro: Very concise.
  • Con: May utilize string logic to determine state.
  • Pro?: Intuitive graphical representation.

Perhaps there is some clever binary logic that can do something clever that I can't even imagine, perhaps there relies too much considerations of the use case.

Also, are there any considerations when adapting a ternary state to store in a database engine? Like Innodb for reference.

  • 12
    Enum: python, java, C#, C, C++, go... – user40980 Jul 3 '14 at 2:46
  • Ibidem, but I'd add that in many languages, enumerated types give you a lot more safety than trying to shoehorn them into some other type. – Blrfl Jul 3 '14 at 2:53
  • 4
    This question is highly dependent on the use-case. In general, all of the listed implementation choices seem appropriate for some different purposes, at different times. – rwong Jul 3 '14 at 3:21
  • 2
    In .NET you can use a nullable boolean. Most databases will allow you to store a boolean (or bit as it is often called) with a nullable state. You can also use a char for storage. The char will allow for more room at a later time without having to change the storage mechanism. – Adam Zuckerman Jul 3 '14 at 4:01
  • 1
    A pointer to bool may also be usable. Bool is forced to 0 and 1 and if the pointer is NULL you have the third state. Depends on the langauge of course. – Devolus Jul 3 '14 at 6:42
6

Apart from an enum which is the obvious and clearest way of expressing this, the system used for interoperable system where a language-specific enum cannot be expressed is the -1/0/1 option.

You may like to try a bitmask though, where 0 means 0, 1 means 'bit 2 set' and 2 means 'bit 3 set' (ie you have 3 bits that can be on or off. As long as you don't define 3, or bits 1 and 2 set, then you're good. This option is best if you think you might need 4 or more flags in the future as 4, 8, 16 etc sets subsequent bits).

All these fit into a single 8-bit datatype so it won't be wasteful of memory or require conversion (as a character based system would, sometimes 16-bit chars are used, sometimes 8-bit depending on your platform).

I wouldn't consider null in any case. Maybe in a database, but only where I could guarantee the system had distinct support for NULLs, and even then it could be error prone if someone didn't explicitly make the distinction and ended up with 0 when it was really null.

  • The best answer on here IMO. NULL could be that it just was not added in the DB, not that its state was 'NULL' having -1,0,1 and possibly NULL - null distinctively indicates that the field was never populated! – Ken Oct 5 '18 at 16:10
2

I do not intend write a clear answer to this question directly; as I commended above, this question is highly dependent on the use-case. In general, all of the listed implementation choices seem appropriate for some different purposes, at different times.

However, I would like to draw your attention to these underlying principles and background knowledge, so that you can make your own informed decision.


On a lighter note, also read this joke: "A businessman asks an accountant; what is two plus two?"

Apologies to all accountants and non-accountants. My mentioning of this joke is intended to highlight the liberty of something we're going to define very soon, and the responsibility and consequences (both in a logical sense) that follows.


Question: what is the truth table of a three-valued logic?

Answer:

... got up from his chair, went over to the door, closed it, came back and sat down. Leaning across the desk,

... And pulls out a hand-drawn chart on a piece of paper.

Operation: Logical And - Confidential - Draft for Q3 2014

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

... he said in a low voice, "how much what would you like those magic values to be?"

A graphics designer asks a programmer, "Can you give an example of three-valued logic?"

Programmer replies, "Can you give me two colors, which is as black and white as they could be?"

Graphic designer: "so ... black, and white?"

Programmer: "exactly. Now I am going to give a third color - but I'll have to specify it as an ARGB number. I hope you don't mind."

Graphic designer: "well I work with ARGB everyday ..."

Black#FF000000
White#FFFFFFFF
Nothing#00000000

Remark. In the above, Black and White are fully opaque colors. The third color, Nothing, is fully transparent. When mixed together in various ratios, Black and White mixes to become various grays, but mixing in Nothing doesn't change anything.

  • I am quite interested by the use of a truth table, Again opening my eyes to the meaning behind my own questions. – ThorSummoner Jul 3 '14 at 16:20
1

If the three possible states have some inherent meaning, use something suitable for that inherent meaning. For example, it the possible states are 1, 2 or 3, or if they are 100, 200 and 300, use an integer. If the possible states are yes, no, or unknown, you might use an optional boolean or a pointer to a boolean object, with the possibility of having no value, a "yes" value, or a "no" value. Although some people might not like it.

If there is an obvious way how integers could be interpreted as possible states, you might use integer. Say a comparison function that has states "less", "equal", "greater" might use -1, 0 and +1. Although some people might not find obvious what you find obvious.

If there is an obvious way how letters could be interpreted as possible states, you might use a character. For example, if your states are "red", "green" or "blue", you might use letters 'r', 'g' and 'b'. Again, what's obvious to you...

An enumerated type is always a possibility. A string is always a possibility, but you lose type checking in most languages.

Some people use three boolean values to represent "is in state 1", "is in state 2", "is in state 3".

Whatever you do, you should be guided by trying to use something that is obvious and understandable, doesn't get you into trouble if suddenly you have four states, and let's the compiler find mistakes as much as possible.

0

What is the best datatype to store a three-state variable? Something capable or representing Positive, Neutral, and Negative.

This depends greatly on the language, what you are doing, abstraction level (which also depends on the language and so on).

I mainly use C++ and there are a lot of choices here. The simplest is an enum tribool_state { false_val, true_val, undetermined_val }. This would be sufficient if your usage scenario is a single function returning this type of value.

I would probably use boost::optional<bool> if I wanted to express a boolean result that may be impossible to get (e.g. check if received network data is complete, then process boolean value if that is the case).

I would use boost::tribool if I wanted to express a fuzzy boolean result that supported full tri-state boolean logic (e.g. true || indetermined -> true, false && indetermined -> false, true && indetermined -> indetermined and so on).

Similarly, in python, I would use a set of constants, or a class (again, depending on what kind of semantics/operations I would need in client code):

For example, I would use:

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

if I had a simple case of a function returning one of three results.

If I had instead a full library requiring tri-state boolean logic, I would implement the value type as a class.

0

If you are using Java, you can use a Boolean object: since it is an object and contains a boolean, it can hold the values true, false, and null. I am not sure if this is the best way though.

-6

In Microsoft.NET, there is a type "Tuple" which can be used for your requirement. Visit http://msdn.microsoft.com/en-us/library/system.tuple%28v=vs.110%29.aspx

  • Per that page: A tuple is a data structure that has a specific number and sequence of elements. An example of a tuple is a data structure with three elements (known as a 3-tuple or triple) that is used to store an identifier such as a person's name in the first element, a year in the second element, and the person's income for that year in the third element. The .NET Framework directly supports tuples with one to seven elements. In addition, you can create tuples of eight or more elements by nesting tuple objects in the Rest property of a Tuple<T1, T2, T3, T4, T5, T6, T7, TRest> object. – Adam Zuckerman Jul 3 '14 at 4:04
  • 1
    That says that a tuple can store any type in up to an octuple (8 dimensions). – Adam Zuckerman Jul 3 '14 at 4:06
  • 1
    recommended reading: Your answer is in another castle: when is an answer not an answer? – gnat Jul 3 '14 at 4:16
  • My Lang-of-choice, Python, also contains a tuple datatype, which a bit of reading suggest, to me anyway, that tuples are appropriate for ternary data. Or potentially a tuple index's value would be the data to store for the use-case and the tuple would be more like a constant. Something about referencing global, or even localized constants by index seems like poor practice to me, unless you are under constraints that prohibit luxuries. – ThorSummoner Jul 3 '14 at 4:21
  • 2
    A tuple is a datatype that can store multiple elements, something like a struct, only dynamically defined. So it would store 3 variables of the type the OP wanted. It doesn't serve to provide the restriction on content he wanted. – gbjbaanb Jul 3 '14 at 7:48

protected by gnat Jun 22 '16 at 8:42

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.