Taking exactly one argument, as compared to a binary operator.

Addition (+) is a binary operator -- it needs two things, one on either side.

Factorial (!) is a unary operator -- it needs one thing, on its left side.

Increment (++) is a unary operator -- it needs one thing, and behaves differently depending on whether its operand is on the left or the right.

The conditional operator ?: is a ternary operator (Larry Wall calls it a trinary operator in the Camel Book) -- it needs three things and returns the second or third depending on whether the first is true or false.

A counting system that uses only one digit. The places in the system follow the same rules as all other counting systems. The number 5 is represented in unary as:
which translates to:

However, this yields: 1 + 1 + 1 + 1 + 1 = 5. Much less interesting than other number systems.

Prime numbers in unary have an interesting property that allows them to be matched by the following perl regular expression:
perl -le '{(1 x ++$_) !~ /^(11+)\1+$/ && print; redo}'

Compare to binary or decimal

If I may expand slightly on Sylvar's excellent writeup:

I dunno about this factorial thing; it looks scary to me. But in C, C++, JavaScript, Java, awk, and a thousand thousand other slimy languages, ! is the boolean negation operator:

    ! TRUE == FALSE
    ! FALSE == TRUE

Other unary operators in all or most of those languages include (but might not be limited to, depending on how porous that lump of useless gray fat rolling around between my ears has become):

~ (tilde): Bitwise complement: ~ 0x0f == 0xfffffff0. Each of the bits is flipped. It's very handy for making bit masks.

Unary -: Makes its operand negative.

Unary +: Makes a negative operand negative, or a positive operand positive. In other words, it does nothing. It was introduced to C by the ANSI standard committee, purely for the sake of symmetry with the unary - operator. I am not making this up.

--: Decrement.

In C, C++, awk, and a few of the others, the increment and decrement operators can appear either before or after the operand. If they appear after, the expression returns the value of the operand before incrementing (or decrementing); if they appear before, the expression returns the value of the operand after it was changed. These are called "post-increment"/"post-decrement" and "pre-increment"/pre-decrement", respectively.


    int i = 4;
    int j;

    j = i++;    //  i == 5, j == 4: assignment before increment of i
    j = ++i;    //  i == 6, j == 6: assignment after increment of i

Counting in unary offers great simplicity and ease of use at the expense of efficiency. Whereas other counting systems try to put more information in each digit, and hence keep overall number length down, unary has the absolute minimum amount of information in each digit, meaning numbers get quite long when expressed using the system.

An example of this is an exercise we all did as children; learning to count to ten on your fingers. This is unary counting, as each number takes up one more digit (pun intended) than its predecessor. However, anyone can see this system is horribly inefficient (well, maybe not the 5-year old doing it). While counting up through the low numbers, most of our fingers are totally unused, wasting many of those god-given appendages:

    one:   1
    two:   11
    three: 111
    four:  1111
    ten:   11111 11111

Contrast this with binary counting, where each finger encodes a whole bit of information:

    one:   00000 00001
    two:   00000 00010
    three: 00000 00011
    four:  00000 00100
    ten:   00000 01010

As you can see, ten can be expressed with room to spare. In fact, you can count up to 31 on only one hand and 1023 when using both!

To make all this a bit more formal, every counting system except unary can express a number, n, in log(n) digits. The base of this logarithm is dependent on the specific system; it's base-2 for binary, base-8 for octal, etc. The important thing is that as a number gets larger, its representation in unary grows just as fast, whereas in any other system, the representation still grows, but more slowly.

So, unary is totally useless and should be phased out? I don't think so. It does have some useful aspects. For example, if we are counting something manually, it would be convenient to be able to simply append to our running total, rather than have to write out the entire new count each time we increment. Unary is the only counting system that offers this, and is used in the traditional "four lines then strikethrough" counting. Also, the simplicity of unary means it is very easy to reason about in mathematical environments. In both computation theory and complexity theory, inputs are often presented in unary for convenience.

However, these are fairly restricted uses of unary; decimal counting is the clear victor, and rightfully so. To express an the age of the universive in years takes only eleven digits in decimal: 13,000,000,000. If we assume about three digts per centimetre, that's exactly three and a bit centimetres. However, in unary, writing that same number would produce a string of ones long enough to stretch around the equator.

Log in or register to write something here or to contact authors.