# Unary representation of floating-point numbers

When the Find the inverse of a number 1/x challenge has been posted, the author posted a bounty for the shortest Retina submission. After that, there was a bounty for sed, another text/string-based language. Since the challenge requires I/O with floating-point numbers, this brings forth a question: how will floating-point numbers be represented in unary?

In unary an integer, say 5, would be represented with that many zeroes, in this case, 00000. What about decimal places? One suggestion was to do the same thing for decimal places as well, for example 4.3 would be 0000.000... BUT what about 4.03? It will share its representation with 4.3, so clearly this way of using unary to show decimal numbers (as in decimal places and not base-10 numbers) would not be valid.

How do we represent floating-point numbers in unary?

• The policy for unary is technically limited to integers. And it's not even clear how negative integers should be represented (I've seen both -000 and --- to represent -3). As for floating point numbers, the most sensible solution would be scientific notation: 4.03 could then be represented as 403 in unary, following 0 in unary. 123.456 would be 123456 in unary, followed by 2 in unary. But we should first discuss whether unary representations for floating point numbers should even be allowed. – Martin Ender Mar 31 '17 at 10:48
• @MartinEnder Don't you mean that 4.03 will be 403 in unary followed by 2 in unary instead? – Cows quack Mar 31 '17 at 10:53
• No, 4.03 is 4.03e0. 4.03e2 would be 403. Your idea of encoding the position of the decimal point in the presented number would also work though. – Martin Ender Mar 31 '17 at 10:56
• @MartinEnder After taking what you have said into account, I say let's first do the discussion on whether unary representations for floating point numbers should even be allowed. If the consensus becomes that unary can be used to represent floating-point numbers, then we should have one meta post to gather up all information on how exactly unary should be used to represent numbers of any sort (be it integer, floating-point, negative, unreal, ...) – Cows quack Mar 31 '17 at 10:59
• Then this post can be deleted while the newer post contains all information on unary representation. – Cows quack Mar 31 '17 at 11:00
• The premise of this question is flawed. "Since the challenge requires I/O with floating-point numbers" - it doesn't: it says "floating point/decimal". There's almost certainly room for argument over whether "decimal" means fixed point or allows rational representation as numerator and denominator (although the latter would make the question even more trivial than it already is), but it seems pretty clear to me that it's not requiring a variable accuracy / precision. – Peter Taylor Mar 31 '17 at 11:30
• @PeterTaylor In reality, the challenge disallows unary submissions, but this post was put up for general challenges that involve mathematical calculations with arbitrary precision numbers – Cows quack Mar 31 '17 at 11:36
• Unary is a bijective numeration; the unary digit is 1, not 0. – Dennis Mar 31 '17 at 15:03
• @Dennis From Wikipedia: in order to represent a number N, an arbitrarily chosen symbol representing 1 is repeated N times. – mbomb007 Mar 31 '17 at 18:16
• @mbomb007 All symbols are chosen arbitrarily; if you want to replace the digits 0 to 9 in a decimal representation with ten different emojis, you're free to do so. That said, 1 is a natural choice for unary. 0 is a particularly bad one; 0 already has a value, and that value isn't 1. – Dennis Mar 31 '17 at 18:30
• Zero doesn't have a representation in unary (other than empty string). Since no other base n contains the symbol n in common usage, (binary has no 2), it makes sense that base 1 doesn't include 1. – mbomb007 Mar 31 '17 at 18:36
• @mbomb007 That's because the bases "in common usage" aren't bijective numerations. Bijective base 2 uses digits 1 and 2, bijective base 10 1 to 10, so bijective base 1 (unary) uses 1. – Dennis Mar 31 '17 at 18:43

## We shouldn't

The question as written puts the cart before the horse. Before asking how to do something, it's always worth asking whether there's any point to doing it. In this case, there is none.

The reason for allowing unary as a number format for natural numbers is that it is the natural way of representing them in some languages. There is no language which has a unary format which is the natural way of representing floating point numbers (or, come to that, fixed point numbers or rational numbers). As the other answers to this question show, it's fitting a round peg into a square hole and it isn't going to help anyone.

• Then I guess the next step would be to create a meta post to ask whether unary should be allowed to represent other types of numbers (floating-point, complex, negative, ...) – Cows quack Apr 4 '17 at 16:07
• @KritixiLithos Why another post? It'd be closed as a duplicate of this one. The answer is right here. Negatives are allowed with -111 already, but that's about it. Considering that complex integers are 1:1 with ZxZ (2D integer coords), you could do 1111+111i or (1111, 111) for complex. – mbomb007 Apr 5 '17 at 14:30
• @mbomb007 What about allowing floating point numbers? – Cows quack Apr 5 '17 at 15:54
• That's literally what this question/answer is about... We shouldn't – mbomb007 Apr 5 '17 at 16:39

I propose the following solution:

4.3   --> 1111.111
4.03  --> 1111.111111111111111111111111111111 (30 '1's)
4.003 --> 1111.111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 (300 '1's)

3.14  --> 111.11111111111111111111111111111111111111111 (41 '1's)
3.41  --> 111.11111111111111    (14 '1's)
1.0   --> 1.
1.10  --> 1.1


Basically, take the decimal number after the decimal point, reverse it, and convert that to unary.

• Simple.

• Doesn't require complex base conversion.

• A unique representation for every number.

Disdvantages:

• Gets really long as precision increases (but this is always a problem with unary)

• Leading zeros are lost (so 4.2 and 4.20 and 4.200000000... all have the same representation)

• Numbers with a periodic representation in base 10 (e.g. 1/3) cannot be represented very precisely.

Overall, the whole problem is weird, so I think this is as good a solution as your going to get.

• I don't see trailing zeroes being lost as a disadvantage; after all, 4.2, 4.20, 4.2000000... are all the same number. – ETHproductions Mar 31 '17 at 20:13
• Also, you may want to include that numbers that are periodic in base 10 (e.g. 1/3) aren't representable in this system. Mine has the same problem, of course... – ETHproductions Mar 31 '17 at 20:21
• @ETHproductions Isn't that also a problem with decimal? – DJMcMayhem Mar 31 '17 at 20:22
• I mean, it's simply not representable. You can have periodic decimals in decimal, but in unary all periodic decimals would just be infinite 1s. You'll have to settle for some set precision level (e.g. 33333 1s; well, now I'm starting to see what you mean...) – ETHproductions Mar 31 '17 at 20:24
• Doesn't using .s make it non-unary? – Comrade SparklePony Mar 31 '17 at 20:42
• @SparklePony No, just like using . in decimal doesn't mean it has 11 digits. – ETHproductions Mar 31 '17 at 20:45
• What if you can represent recurring decimals by introducing another decimal point (after the main unary representation) to show how many digits repeat infinitely? For example, 1/3 could be .111.1 (3 repeating infinitely), and 1/6 could be .{16 1's}.11. – Qwerp-Derp Apr 1 '17 at 0:10
• I agree with @SparklePony if we are introducing a . it is no longer unary. This does not solve the problem that Unary input was introduced to solve. I have trouble seeing how this will help any language compete in a challenge it could not already compete in. – Sriotchilism O'Zaic Apr 2 '17 at 3:11
• @SorghumSorcerer It's not unary anyway because unary representation is only defined for integers, hence the problem that we're trying to solve here. – Mego Apr 2 '17 at 6:39
• @Mego My point is that I don't see how this or any of the solutions actually solve the problem. If a language takes input via unary I really don't see how adding a decimal is going to help. If a language can interpret what a decimal point is and distinguish it from the rest of the input what is stopping them from taking decimal in the first place? – Sriotchilism O'Zaic Apr 2 '17 at 16:52

Use two numbers, a and b, to represent a/2^b or a/2^(b-1), whichever is more convenient. This is like how floating point numbers stored internally in most languages and architectures.

For example, 11111111111 111 means 11/2^3 = 1.375.

I doubt this would be the most natural way to to represent (approximated) real numbers. But you are asking about floating-point numbers, not rationals or fixed-point numbers.

# Unary as a Bijection between the Naturals to the Rationals

My suggestion is simple. You choose your favorite bijection between the natural numbers and the rational numbers and you use it.

There are many such bijections to choose from. Here are two of my favorites:

## Why is this a good idea?

In my opinion including a decimal is not Unary. The reason we allow unary is to allow programming languages that cannot reasonably take input in other ways to compete. Including the decimal altogether defeats the purpose of allowing unary in the first place.

This circumvents the problem by having every natural number correspond to one rational number so that every number can be represented as a sequence of one character (most of the time 1).

It is also pretty flexible, there are many bijections between the natural numbers and the rationals so if one doesn't work for some reason you can always switch to a new one. We don't prescribe a specific bijection that everyone has to follow.

## Drawbacks

While I do believe that this is the best option here it is worth mentioning that mathematical calculations with such numbers may be extremely difficult, especially with languages that have restricted operations.

## Example calculations

Here are some examples using the Stern-Brocot Tree as a bijection.

Decimal | Fraction | Natural number | Unary
1.0  ->   1/1   ->       1       -> 1
.5   ->   1/2   ->       2       -> 11
.75  ->   3/4   ->       11      -> 11111111111
4.0  ->   4/1   ->       15      -> 111111111111111


There are issues with repeating decimals, and I'm not sure if this is a good idea or not, but here we go...

We can introduce a second decimal point, which will tell us how many digits (from the end) are repeated infinitely. This can fit both proposals.

For example, in ETHProductions' proposal, this is how you can represent 1/3:

.11.11


Since 0.01 gets turned into .11, and the 01 bit is repeated infinitely, the second decimal point has two 1s.

This is 1/3 in DJMcMayhem's proposal:

.111.1


Since 0.3 gets turned into .111, and the 3 bit is repeated infinitely, the second decimal point has only one 1.

This should work for all repeating decimals.

More examples in both formats:

1/6:
Decimal:    0.16...               (6 recurs)
Binary:     0.001...              (01 recurs)
ETH format: 0.1111.11
DJ format:  0.{61 1's}.11

1/7:
Decimal:    0.142857...           (142857 recurs)
Binary:     0.001...              (001 recurs)
ETH format: 0.1111.111
DJ format:  0.{758241 1's}.111111

1/11:
Decimal:    0.09...               (09 recurs)
Binary:     0.0001011101...       (0001011101 recurs)
ETH format: 0.{744 1's}.{10 1's}
DJ format:  0.{90 1's}.11


In decimals which aren't repeating, you can just leave the second decimal place out. For example:

1/2:
Decimal:    0.5
Binary:     0.1
ETH format: 0.1
DJ format:  0.11111

• Hmm, interesting idea. I think we might be better off just using / as the separator, though, since we can technically represent any rational number in that way... – ETHproductions Apr 1 '17 at 0:29
• @ETHProductions Yeah, that's pretty true... I personally think this fits well with the main decimal thing. – Qwerp-Derp Apr 1 '17 at 0:33
• So 1/2 would be represented as .1. in my system, or .11111. in DJ's? I guess you could leave off the second decimal point, just as you can with regular integers. Anyway, this would make for an interesting numerical notation of itself, 1/3 being represented concisely as .3.1 in modified decimal, 1/7 as .142857.6... OK, maybe not so concise :P – ETHproductions Apr 1 '17 at 1:28
• Well, it's a reduction of 100%, considering it reduces down an infinite decimal into a finite space... :P – Qwerp-Derp Apr 1 '17 at 1:31

I propose the following solution:

Binary -> Unary
.0    -> .
.1    -> .1
.01   -> .11
.11   -> .111
.001  -> .1111
.101  -> .11111
.011  -> .111111
.111  -> .1111111
.0001 -> .11111111
etc.


That is, to convert the fractional bits of a binary number to unary, reverse the bits, convert to unary, and append the result after the decimal point. As a basic example:

.011 -> 110. -> 6. -> 111111. -> .111111


So 4.375 in decimal would be 1111.111111 in unary (4 -> 1111, .375 -> .111111, as above)

This has the disadvantage of not being able to exactly represent decimal numbers such as 0.7, but of course, binary has the same disadvantage. The difference with this system is that there's no periodic pattern of digits either, but it would be impossible to create a periodic pattern in any unary system; any periodic decimal would just be represented by infinite 1s in unary.

I know this system isn't perfect, but it's a start...

• A "binary decimal" is a contradiction in terms. A representation is either binary (base 2), decimal (base 10), or neither. – Peter Taylor Mar 31 '17 at 20:48
• @PeterTaylor What I mean to say is something along the lines of "the binary digits after the decimal point", if that even makes sense. Is there a term for that that doesn't involve the word "decimal"? – ETHproductions Mar 31 '17 at 20:54
• Fractional bits. – Peter Taylor Mar 31 '17 at 21:09
• @PeterTaylor Ah, thanks. – ETHproductions Mar 31 '17 at 21:32
• @DLosc I'm not sure how that edit improved the wording; I'm converting the fractional bits of a binary number to unary. – ETHproductions Apr 2 '17 at 19:05
• Okay, yes, your current wording is much clearer. – DLosc Apr 3 '17 at 18:27

# 5.3204 => 00000.000 00 0000

Every digit after the decimal point is displayed separately, with a space between every digit. Zero, as you can see, is not displayed and can be noticed by the spaces.

• This isn't unary. It's decimal with a non-standard digit representation. – Peter Taylor Mar 31 '17 at 11:31
• Yeah. A space is a character. – mbomb007 Mar 31 '17 at 18:15