46
\$\begingroup\$

Binary to decimal converter

As far as I can see, we don't have a simple binary to decimal conversion challenge.


Write a program or function that takes a positive binary integer and outputs its decimal value.

You are not allowed to use any builtin base conversion functions. Integer-to-decimal functions (e.g., a function that turns 101010 into [1, 0, 1, 0, 1, 0] or "101010") are exempt from this rule and thus allowed.

Rules:

  • The code must support binary numbers up to the highest numeric value your language supports (by default)
  • You may choose to have leading zeros in the binary representation
  • The decimal output may not have leading zeros.
  • Input and output formats are optional, but there can't be any separators between digits. (1,0,1,0,1,0,1,0) is not a valid input format, but both 10101010 and (["10101010"]) are.
    • You must take the input in the "normal" direction. 1110 is 14 not 7.

Test cases:

1
1

10
2

101010
42

1101111111010101100101110111001110001000110100110011100000111
2016120520371234567

This challenge is related to a few other challenges, for instance this, this and this.

\$\endgroup\$
9
  • \$\begingroup\$ Related \$\endgroup\$
    – mbomb007
    Dec 5, 2016 at 19:43
  • \$\begingroup\$ Does the output have to be unsigned or can it be signed? Also, if my language happens to automatically switch between 32-bit and 64-bit integers depending on the length of the value, can the output be signed in both ranges? Eg- There's two binary values that will convert to decimal -1 (32 1's and 64 1's) \$\endgroup\$
    – milk
    Dec 5, 2016 at 20:47
  • \$\begingroup\$ Also, can the output be floating, do does it need to be an integer? \$\endgroup\$ Dec 5, 2016 at 21:17
  • \$\begingroup\$ @Carcigenicate It must be an integer, but it can be of any data type. As long as round(x)==x you're fine :) 2.000 is accepted output for 10. \$\endgroup\$ Dec 5, 2016 at 21:31
  • 1
    \$\begingroup\$ The last number is the date the challenge was posted? The hours and seconds don't correspond with SE's UTC+0 time, it should be 20161205193745***** :) \$\endgroup\$
    – user60199
    Dec 7, 2016 at 19:52

84 Answers 84

1 2
3
1
\$\begingroup\$

Perl 5, 18 + 1 (-p) = 19 bytes

Combines techniques from the other Perl entries. Scored using the rules at the time of posting.

s/./$\+=$\+$&/ge}{

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Pip, 17 14 bytes

$+(**_*BMERVa)

Doesn't work on TIO because unary ** is only in the latest Pip version.

enter image description here

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ Following my own tips, Isee. \$\endgroup\$
    – Razetime
    Sep 8, 2020 at 3:38
  • \$\begingroup\$ That's 2 of the 3 bytes I saw, and unary ** is another I wasn't including, but there's still one more. (It's one of my tips.) Also, BMER doesn't work because it scans as BM ER not B ME R. \$\endgroup\$
    – DLosc
    Sep 9, 2020 at 2:46
  • \$\begingroup\$ can't seem to find it yet lol \$\endgroup\$
    – Razetime
    Sep 9, 2020 at 2:52
1
\$\begingroup\$

ARM Thumb-2 machine code, 16 bytes

2100 f810 2b01 b112 0852 4149 e7f9 4770

Commented assembly:

        .syntax unified
        .arch armv6t2
        .thumb
        .globl bin2int
        .thumb_func
        // Input: null terminated string in r0
        // Output: integer in r1
bin2int:
        // Set initial result to zero
        movs    r1, #0
.Lloop:
        // Load char from r0 into r2, increment
        ldrb    r2, [r0], #1
        // Was it '\0'? If so, bail.
        cbz     r2, .Lend
        // Shift the lowest bit into the carry flag
        // ASCII '0' has the lowest bit clear, ASCII '1'
        // does not.
        lsrs    r2, r2, #1
        // Multiply the result by 2 (by adding to itself),
        // and add the carry flag to that result
        adcs    r1, r1
        // Jump back to .Lloop (our loop condition is cbz)
        b       .Lloop
.Lend:
        // Return
        bx      lr

The input is a null terminated string in r0 and the output is in r1.

I came up with the same idea as 640KB (SHR/ADC, or in my case, lsrs/adcs) without even seeing their solution. 😛

Great minds think alike, I guess.

\$\endgroup\$
1
\$\begingroup\$

Husk, 5 bytes

Fo+Dd

Try it online!

F        # Fold from left
         # (apply binary function to each element,
         # together with the value of the previous result)
    d    # over all the digits of the input,
         # with this function:
 o       # o = combination of 2 functions
  +      # add second argument (each new digit, from left) to   
   D     # double the first argument (previous result)
\$\endgroup\$
1
\$\begingroup\$

FunStack alpha, 31 bytes

Plus Double compose foldl1 Odd?

Takes a string consisting of 0s and 1s, outputs an integer. Try it at Replit: pass the input string as a command-line argument (formatted like \"1101\") and enter the program on stdin.

Explanation

Same idea as Steffan's Elm answer, Dominic van Essen's Husk answer, etc.

Plus Double compose

Push the functions Plus (dyadic, adds its arguments) and Double (monadic, doubles its argument. Compose them, resulting in a dyadic function that doubles its first argument and adds the result to its second argument.

foldl1

Perform a left fold over a list using that function, with the first element of the list serving as the initial accumulator value. This errors if the list is empty, but we don't have to worry about that since the input represents a positive integer.

Odd?

The list that we want to fold over is the program argument (a string, aka list of characters) with the character '0' turned into the number 0 and similarly for '1' and 1. The obvious way to do this is Minus '0', but since we only have to deal with 0 and 1, we can use Odd? instead. This function returns 1 if its argument is odd and 0 if it is even; when applied to characters, it considers whether the charcode is odd or even.


Another 31-byte answer is possible using a different approach:

Sum Times Pow 2 #N Reverse Odd?

This generates an infinite list of powers of 2, multiplies it by the input digits reversed, and sums the result.

\$\endgroup\$
1
\$\begingroup\$

JavaScript (V8), 28 26 bytes

-2 bytes thank to l4m2!

f=n=>n%2|(n<2?0:2*f(n/10))

Try it online!

Takes input as a Number, outputs a Number.

\$\endgroup\$
1
1
\$\begingroup\$

Go, 70 bytes

func(s string)(o uint64){for _,r:=range s{o=2*o+uint64(r-'0')}
return}

Attempt This Online!

Takes in a string of binary digits (01). For each digit, convert it to it's corresponding number, and add it to twice the total.

\$\endgroup\$
1
  • \$\begingroup\$ r-'0' -> r&1 \$\endgroup\$ Feb 8, 2023 at 5:36
1
\$\begingroup\$

Arturo, 31 bytes

f:$[n][(n>0)?[+2*f n/10n%2]->0]

Try it

\$\endgroup\$
1
\$\begingroup\$

Excel, 51 48 bytes

=NPV(-0.5,MID(n,SORT(SEQUENCE(LEN(n)),,-1),1)/2)

Input n

\$\endgroup\$
1
\$\begingroup\$

Desmos, 51 bytes

f(n)=∑_{i=0}^{log(n+0^n)}2^imod(floor(n/10^i),10)

Try It On Desmos!

Try It On Desmos! - Prettified

Without the ban on binary list input, this could be 33 bytes:

f(l)=total(2^{[l.length-1...0]}l)

Try It On Desmos!

Try It On Desmos! - Prettified

\$\endgroup\$
1
\$\begingroup\$

Commodore C64 BASIC, 84 BASIC Bytes

0inputa$:b=len(a$):ifb=.thenend
1t=.:c=t:forx=bto1step-1:c=c+1:t=t+val(mid$(a$,c,1))*2^(x-1):next:?t

How it works

Firstly, the inputa$ is expecting the user to enter a string, though the only sanity check is that there is something is entered. We then initialise three variables, b to the string length, t to zero (in the Commodore BASIC interpreter, parsing . is slightly quicker than parsing 0), and c also to zero. As we enter the loop, we read each position from right to left.

For each position, the value in c is incremented by 1, and t adds the value of each position multiplied by 2 the power of the current bit position minus 1, and it continues until each position is calculated. The result is then printed.

Binary to decimal converter, Commodore C64

\$\endgroup\$
1
\$\begingroup\$

Thunno 2 S, 4 bytes

drVO

Attempt This Online!

Explanation

drVO  # Implicit input  -> 101010
d     # Cast to digits  -> [1, 0, 1, 0, 1, 0]
 r    # Reverse         -> [0, 1, 0, 1, 0, 1]
  V   # Truthy indices  -> [1, 3, 5]
   O  # Two power       -> [2, 8, 32]
      # S flag sums     -> 42
      # Implicit output 

Old:

dŻrO×  # Implicit input  -> 101010
d      # Cast to digits  -> [1, 0, 1, 0, 1, 0]
 Ż     # Length range    -> [1, 0, 1, 0, 1, 0]  [0, 1, 2, 3, 4, 5]
  r    # Reverse         -> [1, 0, 1, 0, 1, 0]  [5, 4, 3, 2, 1, 0]
   O   # Two power       -> [1, 0, 1, 0, 1, 0]  [32, 16, 8, 4, 2, 1]
    ×  # Multiply        -> [32, 0, 8, 0, 2, 0]
       # S flag sums     -> 42
       # Implicit output
\$\endgroup\$
0
\$\begingroup\$

Pyke, 10 9 bytes

1QY_%0m@s

Try it here!

 QY_      -    reverse digits input
1   %     -   get indecies with a value of 1
     0m@  -  map(set_nth_bit(0, i), ^)
        s - sum(^)

Also 9 bytes

Y_'XltV}+

Try it here!

Y_        - reverse digits
  'Xlt    - splat(^), len(^)-1
      V   - repeat length times:
       }+ -  double and add to stack
\$\endgroup\$
0
\$\begingroup\$

Jelly, 10 bytes

DLḶ2*U,DPS

You know your Jelly code is still golfable when it's above 7 bytes...

It basically consists of two parts
   2*       generate a list of the powers of two
 LḶ         for all the powers of 2 from 0 to the length of the binary input
D           Convert the binary string into a list to get its length with L   
     U      Then upend that list (for '101010', we now have a list of [32, 16, 8, 4, 2, 1]
      ,     Combine this list
       D    with the individual digits of the input  
        P   multiply them with eah other [32*1, 16*0, 8*1, 4*0, 2*1, 1*0]
         S  And sum the result      42 =   32 +  0  +  8 +  0 +  2 +  0

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Mathematica, 44 bytes

2^Range[Length[d=IntegerDigits@#]-1,0,-1].d&

Unnamed function taking an integer argument (interpreted as a base-10 integer, but will only have the digits 0 and 1) and returning an integer. d is set equal to the set of digits, and then the dot product of d with the appropriate sequence of powers of 2 generates the value.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ "You are not allowed to use any builtin base conversion functions." I'd consider IntegerDigits one of those. \$\endgroup\$ Dec 5, 2016 at 22:29
  • \$\begingroup\$ @MartinEnder I think he's using IntegerDigits just to split all the digits in the input. The conversion part is done by 2^Range[...].d \$\endgroup\$ Dec 5, 2016 at 23:54
  • \$\begingroup\$ In any case, JHM's answer is way better than mine :) so let's contemplate the use of IntegerDigits over there. If it's disallowed, JHM and I will presumably use the same string-based preprocessing step, and the other answer will still be better! \$\endgroup\$ Dec 6, 2016 at 0:14
0
\$\begingroup\$

JavaScript, 35 bytes

f=([c,...b],n=0)=>c<2?f(b,+c+n+n):n

For c='1' and c='0', c<2 returns true.
If b is empty, c will be undefined in the next recursion and c<2 will be false.

\$\endgroup\$
1
  • \$\begingroup\$ Hehe ... the 35th answer has 35 bytes. :) \$\endgroup\$
    – Titus
    Dec 5, 2016 at 23:14
0
\$\begingroup\$

Julia 0.5, 22 bytes

!n=n>0&&2*!(n÷10)|n&1

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Keg, -rr, 14 12 bytes

0&÷^⑷2⑻Ë*⑹⑸⅀

Try it online!

Explained

0&              # Place 0 into the register. This will serve as the power to which 2 will be raised
  ÷^            # Take the input as a number and split it into it's individual numbers. It is then reversed.
    ⑷           # Start a map applying the following to each item in the input:
      2⑻Ë*      #   Exponate 2 to the power of the register and multiply the number by that value
          ⑹     #   Increment the register
           ⑸⅀  # Close the map and sum the stack, printing that sum implicitly
\$\endgroup\$
0
\$\begingroup\$

Japt -x, 6 bytes

Ô¬ËÑpE

Try it

\$\endgroup\$
0
\$\begingroup\$

Stax, 4 bytes

╖~♫p

Run and debug it

same reducing idea as Jelly.

\$\endgroup\$
0
\$\begingroup\$

Raku, 33 bytes

{.flip.comb.kv.map(2*** * *).sum}

(If builtins were allowed, this would just be .parse-base(2).)

Explanation:

.flip reverses the string, .comb converts it into a list of chars, .kv inserts the index of each char in front of it. The map block consumes two elements at a time, computing the product of 2 to the power of the first argument (the index) all multiplied by the second argument (the 0 or 1), and the resulting list of products is totaled by .sum.

The asterisks in the map call are doing triple duty: the first two are the exponentiation operator, while the third is a Whatever standing for the first argument to the block (and is the reason the expression becomes a block without curlies). Likewise, the fourth is the standard ASCII multiplication operator, while the fifth is another Whatever representing the second argument. So this ungolfed version does the same thing:

… .map( { 2**$^k × $^v } ) …

Try it online!

\$\endgroup\$
0
\$\begingroup\$

shell with dc, 16 13 10 bytes

There's already a bash + GNU utils, but this solution is POSIX compliant and shorter.

dc -e "10o2i$1p"

It's also a bit quicker (we use internal functioning instead of extra computation, plus there's only one process call instead of two.) But, quoting and extra spaces aren't mandatory

dc -e10o2i$1p

Now, explanation of the expression (-e argument)

  1. 10 o ask to set Output base to decimal.
  2. 2 i ask to set Input base to binary.
    Note that the order matters here. If we issue first 2i, 10o would be read as request to set to binary…
  3. $1 p ask to Print out the entry…
    Read then as binary and expressed in decimal form.

Better, on standard installations with no DC_ENV_ARGS or others (depending your implementation) variable set, default base is decimal. So, finally

dc -e2i$1p

Note : dc is a big bases-converter where i tells how to parse inputs (kinda scanf()) and o tells how to display it (kinda printf()). Values are always stored and manipulated using DCB representation.

\$\endgroup\$
5
  • \$\begingroup\$ But the instructions say “You are not allowed to use any builtin base conversion functions.” \$\endgroup\$
    – doug
    Feb 5, 2023 at 13:57
  • \$\begingroup\$ So the whole command should be discard (in bash answer too): the command is a base conversion itself, but it's not a shell builtin. \$\endgroup\$
    – gildux
    Feb 5, 2023 at 15:44
  • 1
    \$\begingroup\$ It’s not a big deal to me one way or another but I think the point is to do the math operations explicitly. They don’t mention the shell at all, just “builtin” which I assume refers to built in functionality to perform these math operations. Maybe ask for clarification. \$\endgroup\$
    – doug
    Feb 6, 2023 at 5:16
  • \$\begingroup\$ "the point is to do the math operations explicitly." That's a better mention than "You are not allowed to use any builtin base conversion functions." because I just avoid the shell stuff $((2#$1)) and even for dc external command, the i function is a kinda "Integer-to-decimal functions" :s \$\endgroup\$
    – gildux
    Feb 6, 2023 at 19:36
  • 1
    \$\begingroup\$ I may be misreading it, but that's how I understood it. \$\endgroup\$
    – doug
    Feb 6, 2023 at 22:40
0
\$\begingroup\$

TI-Basic, 29 bytes

sum(seq(sub(Ans,length(Ans)-I,1)2^I,I,0,length(Ans)-1

Takes input as a string in Ans.

\$\endgroup\$
0
\$\begingroup\$

Java 8, 54 bytes

Solution using Streams only :

s->s.chars().mapToLong(e->e).reduce(0,(a,b)->2*a+b-48)

Try it online!


If the question didn't require a long, the answer could have been shorter and more elegant (38 bytes) :

s->s.chars().reduce(0,(a,b)->2*a+b-48)
\$\endgroup\$
1 2
3

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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