32
\$\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\$
  • \$\begingroup\$ Related \$\endgroup\$ – mbomb007 Dec 5 '16 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 '16 at 20:47
  • \$\begingroup\$ Also, can the output be floating, do does it need to be an integer? \$\endgroup\$ – Carcigenicate Dec 5 '16 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\$ – Stewie Griffin Dec 5 '16 at 21:31
  • \$\begingroup\$ Oh sweet. Thanks. \$\endgroup\$ – Carcigenicate Dec 5 '16 at 21:33

55 Answers 55

1
\$\begingroup\$

JavaScript (ES7), 56 47 bytes

Reverses a binary string, then adds each digit's value to the sum.

n=>[...n].reverse().reduce((s,d,i)=>s+d*2**i,0)

Demo

f=n=>[...n].reverse().reduce((s,d,i)=>s+d*2**i,0)
document.write( f('101010') ) // 42

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

Java 7, 87 bytes

long c(String b){int a=b.length()-1;return a<0?0:b.charAt(a)-48+2*c(b.substring(0,a));}

For some reason I always go straight to recursion. Looks like an iterative solution works a bit nicer in this case...

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

JavaScript (ES6), 38

Simple is better

s=>eval("for(i=v=0;c=s[i++];)v+=+c+v")

Test

f=s=>eval("for(i=v=0;c=s[i++];)v+=+c+v")

console.log("Test 0 to 99999")
for(e=n=0;n<100000;n++)
{  
  b=n.toString(2)
  r=f(b)
  if(r!=n)console.log(++e,n,b,r)
}
console.log(e+" errors")

  

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

Turing Machine Code, 272 bytes

(Using, as usual, the morphett.info rule table syntax)

0 * * l B
B * * l C
C * 0 r D
D * * r E
E * * r A
A _ * l 1
A * * r *
1 0 1 l 1
1 1 0 l 2
1 _ * r Y
Y * * * X
X * _ r X
X _ _ * halt
2 * * l 2
2 _ _ l 3
3 * 1 r 4
3 1 2 r 4
3 2 3 r 4
3 3 4 r 4
3 4 5 r 4
3 5 6 r 4
3 6 7 r 4
3 7 8 r 4
3 8 9 r 4
3 9 0 l 3
4 * * r 4
4 _ _ r A

AKA "Yet another trivial modification of my earlier base converter programs."

Try it online, or you can also use test it using this java implementation.

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

JavaScript, 18 83 bytes

f=n=>parseInt(n,2)

f=n=>n.split('').reverse().reduce(function(x,y,i){return(+y)?x+Math.pow(2,i):x;},0)

Demo

f=n=>n.split('').reverse().reduce(function(x,y,i){return(+y)?x+Math.pow(2,i):x;},0)
document.write(f('1011')) // 11

\$\endgroup\$
  • \$\begingroup\$ Uses a built-in, which is disallowed. \$\endgroup\$ – Yytsi Dec 5 '16 at 21:41
  • \$\begingroup\$ @TuukkaX Ah, missed that. Thanks. \$\endgroup\$ – Oliver Dec 5 '16 at 21:42
  • 1
    \$\begingroup\$ I was just about to do the same thing (in c#), I'm bad at reading. \$\endgroup\$ – Yodle Dec 5 '16 at 21:42
  • \$\begingroup\$ It's a code golf challenge, try to write short code. (y==='1') could be +y \$\endgroup\$ – edc65 Dec 5 '16 at 22:01
1
\$\begingroup\$

MATL, 7 bytes

PoofqWs

Try it online!

P   % Implicitly input string. Reverse
o   % Convert to array of ASCII codes
o   % Modulo 2: '1' becomes 1, '0' becomes 0
f   % Find: push array of 1-based indices of nonzeros
q   % Subtract 1 from each entry
W   % 2 raised to each entry
s   % Sum of array. Implicitly display
\$\endgroup\$
  • 2
    \$\begingroup\$ My mind went Poof! \$\endgroup\$ – Adám Dec 12 '16 at 14:54
1
\$\begingroup\$

MATL, 8, 7 bytes

"@oovsE

Try it online!

One byte saved thanks to @LuisMendo!

Alternate approach: (9 bytes)

ootn:PW*s
\$\endgroup\$
1
\$\begingroup\$

Befunge, 20 18 bytes

Input must be terminated with EOF rather than EOL (this lets us save a couple of bytes)

>+~:0`v
^*2\%2_$.@

Try it online!

Explanation

>             The stack is initially empty, the equivalent of all zeros.
 +            So the first pass add just leaves zero as the current total. 
  ~           Read a character from stdin to the top of the stack.
   :0`        Test if greater than 0 (i.e. not EOF)
      _       If true (i.e > 0) go left.
    %2        Modulo 2 is a shortcut for converting the character to a numeric value.
   \          Swap to bring the current total to the top of the stack.
 *2           Multiply the total by 2.
^             Return to the beginning of the loop,
 +            This time around add the new digit to the total.

                ...on EOF we go right...
       $      Drop the EOF character from the stack.
        .     Output the calculated total.
         @    Exit.
\$\endgroup\$
  • \$\begingroup\$ I had like a 60-something byte code that was dealing with integers, and wow, this is so much more simple and elegant. Great job, and nice explanation too. \$\endgroup\$ – MildlyMilquetoast Dec 6 '16 at 5:14
1
\$\begingroup\$

Ruby, 37 bytes

ruby -e 'o=0;gets.each_byte{|i|o+=o+i%2};p o/2'
         1234567890123456789012345678901234567

This depends on the terminating \n (ASCII decimal 10) being zero modulo 2 (and on ASCII 0 and 1 being 0 and 1 mod two, respectively, which thankfully they are).

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

아희(Aheui), 40 bytes

아빟뱐썩러숙
뎌반뗘희멍파퍄

Accepts a string composed of 1s and 0s.

To try online

Since the online Aheui interpreter does not allow arbitrary-length strings as inputs, this alternative code must be used (identical code with slight modifications):

Add the character at the end of the first line (after ) length(n)-times.

어우
우어
뱐썩러숙
번댜펴퍼망희땨

If the input is 10110, the first line would be 어우벟벟벟벟벟.

When prompted for an input, do NOT type quotation marks. (i.e. type 10110, not "10110")

Try it here! (copy and paste the code)

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

ClojureScript, 36 bytes

(fn[x](reduce #(+(* 2 %)(int %2))x))

or

#(reduce(fn[a n](+(* 2 a)(int n)))%)

The straightforward reduction. Takes a string as input.

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

Minkolang v0.15, 23 19 bytes

n6ZrI[2%2i;*1R]$+N.

Try it online!

Explanation

n                             gets input in the form of a number
 6Z                           converts to string (so that it is split into an array)
   r                          reverses it
    I                         gets the stack length
     [        ]               for loop with the stack's length as the number of iterations
      2%                       gets the modulo of the ascii value
                               1 =(string conversion)> 49 =(after modulo)> 1
                               0 =(string conversion)> 48 =(after modulo)> 0
        2i;                    raises 2 to the power of the loop counter
           *                   multiplies it by the modulo
            1R                 rotates stack 1 time
              $+              sums everything
                N.            outputs as number and exit
\$\endgroup\$
1
\$\begingroup\$

Common Lisp, 99 88 72 bytes

Takes a string as input

(defun f(s)(reduce(lambda(a d)(+ d(* a 2)))(map'list #'digit-char-p s)))

Ungolfed:

(defun bin-to-dec (bin-str)
  (reduce (lambda (acc digit) (+ digit (* acc 2)))
          (map 'list #'digit-char-p bin-str)))
\$\endgroup\$
1
\$\begingroup\$

><> (Fish) 36 28 bytes

/i:1+?!v$2*$2%+!| !
/0| ;n~<

Edit 1: Forgot to put the output in the original. Added output and used MOD 2 instead of minus 48 to convert ascii to decimal to save the extra bytes lost. (no change in bytes)

Edit 2: Changed the algorithm completely. Each loop now does this; times current value by 2, then add the mod of the input. (saving of 8 bytes)

Online version

Try it Online! - This works with bigger numbers than the above link.

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

C, 44 bytes

d(s,v)char*s;{return*s?d(s,v+=v+*s++-48):v;}

Use as follows :

int main(){
  printf("%i\n", d("101010",0));
}

Remove two bytes and an unused parameter thanks to Steadybox

\$\endgroup\$
  • \$\begingroup\$ You have an unused parameter c there. Removing it saves two bytes. \$\endgroup\$ – Steadybox Dec 6 '16 at 19:49
1
\$\begingroup\$

Haskell, 31 bytes

f=foldl(\a b->2*a+(read$b:[]))0

Takes input in string format (e.g. "1111"). Produces output in integer format (e.g. 15).

:[] Converts from an element to an array -- in this chase from Char to [Char] (String). read Converts from string to whatever context it's in (in this case the context is addition, so converts to Num)

so (read$b:[]) converts b from Char to Num. a is the accumulator, so multiply that by two and add the Num version of b.

If input in the format [1,1,1,1] was allowed, the 18 byte

f=foldl((+).(2*))0

would work, but since it's not, it doesn't.

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

MATLAB, 49 bytes

@(a)dot(int2str(a)-'0',2.^(floor(log10(a)):-1:0))

Anonymous function that splits the input into an array with int2str(a)-'0', then does a dot product with powers of 2. Has rounding error for the last test case, will update the solution when I figure out a fix.

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

Forth (gforth 0.7.3), 47 bytes

: x 2 base ! bl parse s>number drop decimal . ;

: x - define new word with name 'x'
2 base ! - set base to binary
bl parse - read line until a space (bl) or EOL
s>number - try to convert the string to number
drop - we only want the converted number and not the success flag
decimal - set base to decimal
. - print value on top of stack
; - end of definition

Test cases:

x 1 1  ok
x 10 2  ok
x 101010 42  ok
x 1101111111010101100101110111001110001000110100110011100000111 2016120520371234567  ok
\$\endgroup\$
  • \$\begingroup\$ Sorry, forget my last comment, I thought this answer was to another challenge :/ The answer is perfectly valid :) \$\endgroup\$ – Stewie Griffin Dec 23 '16 at 12:09
1
\$\begingroup\$

C, 41 37 bytes

i;b(char*s){i+=i+*s++%2;i=*s?b(s):i;}

Wandbox

\$\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\$
  • 1
    \$\begingroup\$ "You are not allowed to use any builtin base conversion functions." I'd consider IntegerDigits one of those. \$\endgroup\$ – Martin Ender Dec 5 '16 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\$ – JungHwan Min Dec 5 '16 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\$ – Greg Martin Dec 6 '16 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\$
  • \$\begingroup\$ Hehe ... the 35th answer has 35 bytes. :) \$\endgroup\$ – Titus Dec 5 '16 at 23:14
0
\$\begingroup\$

Julia 0.5, 22 bytes

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

Try it online!

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

SmileBASIC, 47 44 bytes

INPUT B$WHILE""<B$N=N*2+VAL(SHIFT(B$))WEND?N

Another program of the same size:

INPUT B$WHILE""<B$N=N*2OR"0"<SHIFT(B$)WEND?N
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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