1

I have tried this

function binToDec(num) {
    let dec = 0; 
    for(let i = 0; i < num.length; i++) {
        if(num[num.length - (i + 1)] === '1') {
            dec += 2 ** i;
        }
    }
    return dec;
}

console.log(binToDec('1010'));

this code is not mine and it works but i want to know how it converts the binary number to decimal and it will be very helpful is you could tell me another way to do it.

I have also tried this

function binToDec(num) {
    let bin = parseInt(num, 2);
    return bin;
}
console.log(binToDec(1010));

I know this also work but i am not looking for this answer.

thank you for your help.

0

2 Answers 2

2

I just starts with the last character of the string and adds the value of this position to the result.

string    dec
------  -------
 1010    0
    0    0
   1     0 + 2
  0      2
 1       2 + 8
------  ------
        10

function binToDec(num) {
    let dec = 0;
    for (let i = 0; i < num.length; i++) {
        if (num[num.length - (i + 1)] === '1') {
            dec += 2 ** i;
        }
    }
    return dec;
}

console.log(binToDec('1010')); // 10

Another way is to start with the left side of the sting and

  • multiply the converted value by the base (2) and
  • add the value of the string.

The result is now the converted number. This works for all bases, as long as the value at the index is converted to a number.

function binToDec(num) {
    let dec = 0;
    for (let i = 0; i < num.length; i++) {
        dec *= 2;
        dec += +num[i];
    }
    return dec;
}

console.log(binToDec('1101')); // 13

Sign up to request clarification or add additional context in comments.

2 Comments

Sorry for the late comment but it is possible log the number as number instead of string and still return true because when i change '1010' to 1010 it return 0
which true do you want? and where?
1

Explanation

Think of how base 10 works.

909 = 900 + 9
    = (9 *   100) + (0 *    10) + (9 *     1)
    = (9 * 10**2) + (0 * 10**1) + (9 * 10**0)

As you can see, a natural number in base 10 can be seen as a sum where each term is in the form of:

digit * base**digit_position

This is true for any base:

base 2 : 0b101 = (0b1 * 2**2) + (0b0 * 2**1) + (0b1 * 2**0)
base 16 : 0xF0F = (0xF * 16**2) + (0x0 * 16**1) + (0xF * 16**0)

Therefore, here is a possible abstraction of a natural number:

function natural_number (base, digits) {
  var sum = 0;
  for (var i = 0; i < digits.length; i++) {
    digit = digits[i];
    digit_position = digits.length - (i + 1);
    sum += digit * base**digit_position;
  }
  return sum;
}
> | natural_number(2, [1, 0, 1]) // 1 * 2**2 + 1 * 2**0
< | 5
> | natural_number(10, [1, 0, 1]) // 1 * 10**2 + 1 * 10**0
< | 101
> | natural_number(16, [1, 0, 1]) // 1 * 16**2 + 1 * 16**0
< | 257

Your own function takes only binary numbers (base 2). In this case digit can be either 0 or 1, that's all. We know that it's useless to multiply something by 0 or 1, so the addition can be replaced with:

if (digit === 1) {
  sum += 2**digit_position;
}

Which is the equivalent of:

if (num[num.length - (i + 1)] === '1') {
  dec += 2 ** i;
}

Do you get it? :-)

Alternative

You don't feel confortable with the exponentiation operator (**)? There is a workaround. Did you ever notice that multiplying a number by 10 is nothing more than shifting its digits one time to the left?

909 * 10 = 9090

Actually, shifting a number to the left boils down to multiplying this number by its base:

number *= base

This is true for any base:

base 2 : 0b11 * 2 = 0b110
base 16 : 0xBEE * 16 + 0xF = 0xBEE0 + 0xF = 0xBEEF

Based on this, we can build an algorithm to convert an array of digits into a number. A trace of execution with [9,0,9] in base 10 as input would look like this:

init  |   0 | n = 0
add 9 |   9 | n += 9
shift |  90 | n *= 10
add 0 |  90 | n += 0
shift | 900 | n *= 10
add 9 | 909 | n += 9

Here is a possible implementation:

function natural_number (base, digits) {
  var n = 0;
  for (var i = 0; i < digits.length; i++) {
    n += digits[i];
    if (i + 1 < digits.length) {
      n *= base;
    }
  }
  return n;
}

Of course this function works the same as before, and there is a good reason for that. Indeed, unroll the for loop that computes [9,0,9] in base 10, you get this:

return ((0 + 9) * 10 + 0) * 10 + 9;

Then expand this expression:

((0 + 9) * 10 + 0) * 10 + 9
= (0 + 9) * 10 * 10 + 0 * 10 + 9
= 9 * 10 * 10 + 0 * 10 + 9
= 9 * 10**2 + 0 * 10**1 + 9 * 10**0

Do you recognize the equation discussed earlier? :-)

Bonus

Reverse function:

function explode_natural_number (base, number) {
  var remainder, exploded = [];
  while (number) {
    remainder = number % base;
    exploded.unshift(remainder);
    number = (number - remainder) / base;
  }
  return exploded.length ? exploded : [0];
}
> | explode_natural_number(2, 5)
< | [1, 0, 1]
> | explode_natural_number(3, 5) // base 3 (5 = 1 * 3**1 + 2 * 3**0) :-)
< | [1, 2]
> | explode_natural_number(16, natural_number(16, [11, 14, 14, 15])) // 0xBEEF
< | [11, 14, 14, 15]

String to number and number to string:

function parse_natural_number (number, base) {
  var ZERO = 48, A = 65; // ASCII codes
  return natural_number(base, number.split("").map(function (digit) {
    return digit.toUpperCase().charCodeAt(0);
  }).map(function (code) {
    return code - (code < A ? ZERO : A - 10);
  }));
}

function stringify_natural_number (number, base) {
  var ZERO = 48, A = 65; // ASCII codes
  return String.fromCharCode.apply(
    String, explode_natural_number(base, number).map(function (digit) {
      return digit + (digit < 10 ? ZERO : A - 10);
    })
  );
}
> | stringify_natural_number(parse_natural_number("48879", 10), 16)
< | "BEEF"
> | parse_natural_number("10", 8)
< | 8

More levels of abstraction for convenience:

function bin_to_dec (number) {
  return parse_natural_number(number, 2);
}

function oct_to_dec (number) {
  return parse_natural_number(number, 8);
}

function dec_to_dec (number) {
  return parse_natural_number(number, 10);
}

function hex_to_dec (number) {
  return parse_natural_number(number, 16);
}

function num_to_dec (number) {
  switch (number[0] + number[1]) {
    case "0b" : return bin_to_dec(number.slice(2));
    case "0x" : return hex_to_dec(number.slice(2));
    default : switch (number[0]) {
      case "0" : return oct_to_dec(number.slice(1));
      default : return dec_to_dec(number);
    }
  }
}
> | oct_to_dec("10")
< | 8
> | num_to_dec("010")
< | 8
> | 010 // :-)
< | 8
function dec_to_bin (number) {
  return stringify_natural_number(number, 2);
}
> | dec_to_bin(8)
< | "1000"

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.