37
\$\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

65 Answers 65

2
\$\begingroup\$

Dyalog APL, 12 bytes

(++⊢)/⌽⍎¨⍞

get string input

⍎¨ convert each character to number

reverse

(...)/ insert the following function between the numbers

++⊢ the sum of the arguments plus the right argument


ngn shaved 2 bytes.

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Excel, 74 70 55

Trailing parens already discounted. Tested in Excel Online.

Formulae:

  • A1: Input
  • B1: =LEN(A1) (7)

Main Code (48):

A pretty simple "add all the powers of 2" formula:

=SUM(MID(A1,1+B1-SEQUENCE(B1),1)/2*2^SEQUENCE(B1))

Verify with:

=DECIMAL(A1,2)
| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

R, 48 37 bytes

-11 bytes thanks to Dominic van Essen

sum(utf8ToInt(scan(,""))%%2*2^(31:0))

Takes input as a string, left-padded with 0s to 32 bits. Try it online!

I copied some good ideas from djhurio's much earlier R answer, so go give that an upvote too. As with the first solution there, this solution won't work for the last test case because it's too large to fit into R's default size of integer.

Explanation

To get a vector of the bits as integers 0 and 1, we use uft8ToInt to convert to a vector of character codes. This gives us a list of 48s and 49s, which we take mod 2 to get 0s and 1s.

Then, to get the appropriate powers of 2 in descending order, we construct a range from 31 down to 0. Then we convert each of those numbers to the corresponding power of two (2^).

Finally, we multiply the two vectors together and return their sum.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ 37 bytes (or 40 bytes as a function) thanks to 'You may choose to have leading zeros in the binary representation'. Accepts input as 32-bit binary string, with leading zeros, but easily modified to double-integer precision for the same length code... \$\endgroup\$ – Dominic van Essen Sep 9 at 7:19
1
\$\begingroup\$

k, 8 bytes

Same method as the Haskell answer above.

{y+2*x}/

Example:

{y+2*x}/1101111111010101100101110111001110001000110100110011100000111b
2016120520371234567
| improve this answer | |
\$\endgroup\$
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

| improve this answer | |
\$\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...

| improve this answer | |
\$\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")

  

| improve this answer | |
\$\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.

| improve this answer | |
\$\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

| improve this answer | |
\$\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, 8, 7 bytes

"@oovsE

Try it online!

One byte saved thanks to @LuisMendo!

Alternate approach: (9 bytes)

ootn:PW*s
| improve this answer | |
\$\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.
| improve this answer | |
\$\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).

| improve this answer | |
\$\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)

| improve this answer | |
\$\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.

| improve this answer | |
\$\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
| improve this answer | |
\$\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)))
| improve this answer | |
\$\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.

| improve this answer | |
\$\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

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ You have an unused parameter c there. Removing it saves two bytes. \$\endgroup\$ – Steadybox Dec 6 '16 at 19:49
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.

| improve this answer | |
\$\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
| improve this answer | |
\$\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

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

APL(NARS), 26 chars, 52 bytes

{+/a×⌽1,2x*⍳¯1+≢a←1-⍨⎕D⍳⍵}

test:

  f←{+/a×⌽1,2x*⍳¯1+≢a←1-⍨⎕D⍳⍵}
  ⎕fmt f"0"
0
~
  f"1"
1
  ⎕fmt f"101010"
42
~~
  f"10"
2 
  (≢,f)"11011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
152 4995366924470859583704000893073232977339613183 

152 bits... It should be limited from memory for store string and numbers.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

7, 25 bytes (65 characters)

07717134200446170134271600446170001755630036117700136161177546635

Try it online!

Explanation

077                             Initialize counter to 0 (an empty section)
   17134200..77546635           Push the main loop onto the frame

Once the original code has finished executing, the frame is

||6||7134200447013427160044700017556300377700136177754635

The last section of this is the main loop, which will run repeatedly until it gets deleted. All of it except the last two commands is data and section separators, which push commands onto the frame to leave it as:

||6|| (main loop) |73426644|6734216644|6667553663||00137||54

3 outputs the last section (54) and discards the last two bars. On the first iteration, 5 is interpreted as a switch to output format 5 ("US-TTY"), which converts each pair of commands to a character. The 4 following it does not form a group, so it is ignored. On future iterations, we are already in output format 5, so 54 is interpreted as a group meaning "input character". To do this, the character from STDIN is converted into its character code (or, on EOF, -1), and 1 is added. Then, the last section (which is now the 00137) is repeated that many times. In summary:

  • If the character is 0, 00137 is repeated 49 times.
  • If the character is 1, 00137 is repeated 50 times.
  • If there are no more characters, 00137 is repeated 0 times (i.e. deleted).
  • If this was the first iteration, 00137 is left alone (i.e. repeated 1 time).

5 removes the last section (00137 repeated some number of times) from the frame and executes it, resulting in this many sections containing 6673.

The main loop has now finished executing, so the last section (which is 6673 unless we reached EOF) runs. 66 concatenates the last three sections into one (and has some other effects that don't affect the number of sections), which 73 deletes. Thus, the last three sections are deleted, and this repeats until the last section is no longer 6673.

  • If we reached EOF, nothing happens.
  • If this is the first iteration or the character was 0, after removing the last three sections 0 or 16 times, there is just one copy left on the frame. This copy deletes itself and the two sections before it, leaving everything up to the main loop and the section after it.
  • If the character was 1, after removing the last three sections 17 times, all 50 copies and the third section after the main loop (the EOF handler) have been deleted.

Now, the last section left on the frame runs. This could, depending on the inputted character, be any of the three sections after the main loop.

If this is the first iteration or the character was 0, the section just after the main loop, 73426644, runs. 73 deletes this section, and 4 swaps the main loop with the counter behind it. This counter keeps track of the number we want to output, stored as the number of 7s and 1s minus the number of 6s and 0s. This metric has the property that it is not changed by pacification (which changes some 6s into 0s, some 7s into 1s, and sometimes inserts 7...6 around code). 2 duplicates the counter and 6 concatenates the two copies (after pacifying the second, which, as we saw, does not change the value it represents), so the value is doubled. If this was the first iteration, the counter was previously empty, and doubling it still results in an empty section. Then, 6 gets rid of the empty section inserted by 4 (and pacifies the counter again, leaving the value unchanged), and 44 swaps the counter back to its original position. This leaves two empty sections on the end of the frame, which are removed automatically, and the main loop runs again.

If the character was 1, the second section after the main loop (6734216644) runs. This is just like the section before it (explained in the last paragraph), except for two extra commands: a 6 at the start, which joins the section with the previous one before 73 deletes it, and a 1 in the middle, which adds a 7 to the counter (increasing its value by 1) after it gets doubled.

If we reached EOF, the third section after the main loop (6667553663) runs. 666 joins the last four sections (everything after the counter) into one section, to be deleted by 3. 7553 exits output format 5 by outputting 55 and deletes the section before it, leaving only ||6| (counter) on the frame. 66 pacifies the two sections and combines them, turning the 6 back into a 0 (and not changing the value of the counter). Finally, the last 3 outputs everything. The 0 at the start enters output format 0 ("Numerical output"), and the rest of the section (i.e. the counter) is converted to a number by taking the number of 7s and 1s minus the number of 6s and 0s. This value, which is the input converted from binary, is output in decimal and the program terminates.

| improve this answer | |
\$\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!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Following my own tips, Isee. \$\endgroup\$ – Razetime Sep 8 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 at 2:46
  • \$\begingroup\$ can't seem to find it yet lol \$\endgroup\$ – Razetime Sep 9 at 2:52
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
| improve this answer | |
\$\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!

| improve this answer | |
\$\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.

| improve this answer | |
\$\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.

| improve this answer | |
\$\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!

| improve this answer | |
\$\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
| improve this answer | |
\$\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.