Convert Decimal to Binary in JavaScript

Beginner
⏱️ 9 min read
📚 Updated: May 2026
🎯 2 Code examples + Try it
Base conversion

What you’ll learn

  • How division by two and remainders yield binary digits from right to left.
  • Why you must handle zero and why the first implementation prints the array backwards.
  • An MSB-first bit walk for n >>> 0 (32-bit unsigned view), a live preview, and links to the inverse tutorial.

Overview

Binary uses powers of two. To express a nonnegative decimal integer in base two, repeatedly divide by 2 and record remainders 0 or 1; read those bits from last generated to first for MSB-first output.

Two programs

Remainder stack in an array (classic), then bit scan MSB-first with >>>.

Live preview

Nonnegative safe integers; mirrors (n >>> 0).toString(2) for the 32-bit unsigned view.

Inverse

Pair with binary to decimal for a full interview story.

Prerequisites

Integer division and modulo, arrays, for loops, and optional bitwise operators (>>>, &).

  • console.log, Number.isSafeInteger, and n >>> 0 for unsigned 32-bit coercion.
  • Why Number#toString(2) is handy for checks, but interviews still want the manual loops.

Decimal to binary

Each binary digit (bit) is a coefficient on a power of two. Converting a nonnegative integer n collects those bits by peeling parity: n % 2 is the least significant bit, then n = Math.floor(n / 2) shifts right in value.

Example: 15 = 8 + 4 + 2 + 1 = 1·23 + 1·22 + 1·21 + 1·20, written 11112.

Decimal base 10
Binary base 2
Example 15 → 1111

Division algorithm

For n ≥ 0, define b0 = n mod 2, n1 = ⌊n/2⌋, then b1 = n1 mod 2, and so on until the quotient is 0. The sequence bk…b0 (reversed index) is the binary expansion of n.

15

15 = 2·7 + 1, 7 = 2·3 + 1, 3 = 2·1 + 1, 1 = 2·0 + 1 → bits from LSB up: 1 1 1 11111.

Intuition

8 1000₂
Power
23
5 101₂
Sum
4 + 1

Takeaway: each division step answers “odd or even?” at the current scale—that is the next bit.

Live preview

Nonnegative integers in the JavaScript safe range. Uses Number#toString(2) for a quick binary string.

Negative values are rejected here; signed two's complement is a separate convention.

Live result
Press “Show binary” to convert.

Algorithm (remainder method)

Goal: print bits of nonnegative n in MSB-first order.

Special case n == 0

Print a single 0 and stop (the pure while (n > 0) loop prints nothing otherwise).

Collect bits

While n > 0: push n % 2, then n = Math.floor(n / 2).

Print reversed

Emit stored bits from last pushed down to first.

📜 Pseudocode

Pseudocode
function printBinaryFromDecimal(n):  // n ≥ 0
    if n = 0:
        output "0"; return
    bits ← empty list
    while n > 0:
        append (n mod 2) to bits
        n ← floor(n / 2)
    print bits in reverse order
1

Divide by two with reverse print

Same structure as the reference, with an explicit zero branch. Uses n >>> 0 so inputs match a 32-bit unsigned view (like unsigned int in C).

JavaScript
function decimalToBinary(decimalNumber) {
  const binaryDigits = [];
  let n = decimalNumber >>> 0;

  if (n === 0) {
    console.log("Binary equivalent: 0");
    return;
  }

  while (n > 0) {
    binaryDigits.push(n % 2);
    n = Math.floor(n / 2);
  }

  let line = "Binary equivalent: ";
  for (let j = binaryDigits.length - 1; j >= 0; j--) {
    line += String(binaryDigits[j]);
  }
  console.log(line);
}

const decimalNumber = 15 >>> 0;

decimalToBinary(decimalNumber);
decimalToBinary(0);
Try it Yourself

Explanation

>>> 0 coerces to unsigned 32-bit, avoiding sign surprises while dividing by two.

for (let j = binaryDigits.length - 1; j >= 0; j--)

MSB first. The last remainder pushed is the highest bit of the original value.

2

MSB-to-LSB with a bit scan

No reversal buffer: scan from bit 31 down to 0 on n >>> 0, skip leading zeros unless the value is 0. Uses (u >>> b) & 1 so we never build 1 << 31 as a signed mask.

JavaScript
function printBinaryMsb32(n) {
  const u = n >>> 0;
  if (u === 0) {
    return "0";
  }

  let started = false;
  let out = "";
  for (let b = 31; b >= 0; b--) {
    const bit = (u >>> b) & 1;
    if (bit || started) {
      out += bit ? "1" : "0";
      started = true;
    }
  }
  return out;
}

console.log("15 as binary: " + printBinaryMsb32(15));
console.log("64 as binary: " + printBinaryMsb32(64));
Try it Yourself

Explanation

The started flag suppresses leading zeros; the first 1 begins the meaningful prefix.

(u >>> b) & 1

Unsigned shift. Reads bit b without shifting a 1 into the sign bit of a signed 32-bit pattern.

Optimization

Find MSB once. For u > 0, start at bit 31 - Math.clz32(u) instead of scanning all 32 positions (Math.clz32 counts leading zeros on a 32-bit value).

Recursive print. Print Math.floor(n/2) first then n % 2 to emit MSB-first without storage (mind recursion depth for huge types).

Interview: mention n==0, >>> 0 for bit view, and inverse conversion.

❓ FAQ

The first remainder from n/2 is the least significant bit (parity). Each later remainder is the next higher bit. Printing from last remainder to first walks MSB to LSB.
while (n > 0) never runs, so nothing is printed. Handle n == 0 as a special case that outputs a single 0.
It tests bits from a fixed high position down (here 31 down to 0 for a 32-bit unsigned view via n >>> 0), skipping leading zeros except when the value is 0. No temporary array is required.
Plain division on negative numbers does not give a minimal unsigned bit string. For two's complement of 32 bits, coerce with (n >>> 0) to reinterpret bits as unsigned, and document that choice—or use BigInt for arbitrary width.
Either enough for your problem (e.g. 8 bits) or from the highest set bit down (variable width). Fixed 32-bit dumps match (n >>> 0) in JavaScript bitwise semantics.
O(b) for b output bits: about log2(n) for positive n in the remainder method, or O(W) for a fixed width W in the mask scan.

🔄 Input / output examples

Example 1 uses 15 and 0; Example 2 shows 15 and 64.

DecimalBinary (minimal)
00
11
151111
641000000

Edge cases and pitfalls

Signed division with negative n does not implement “binary string of absolute value”; pick n >>> 0 or document two's complement.

Zero

n == 0

Must print 0; the naive remainder loop alone prints an empty line.

Width

Fixed 8 vs minimal

Hardware often wants padded width (00001111); interview questions should state padding rules.

Shift

1 << 31 on signed 32-bit

In JavaScript bitwise ops are 32-bit signed; 1 << 31 is negative. Prefer (u >>> b) & 1 or unsigned typed arrays when testing masks.

Inverse

Binary to decimal

See the paired tutorial for Horner / digit peel when the input is a bit string.

⏱️ Time and space complexity

ApproachTimeExtra space
Remainder + arrayO(log n) bitsO(log n) digits stored
32-bit mask scanO(32) = O(1)O(1)
MSB via Math.clz32O(1)O(1)

log is base 2 in the bit-length sense for nonnegative n.

Summary

  • Idea: collect n % 2 while halving n; print in reverse, or scan bits MSB-down.
  • Code: handle 0; prefer n >>> 0 for a 32-bit unsigned bit pattern.
  • Pair: binary-to-decimal for the reverse direction.
Did you know?

Repeated division by 2 collects bits from least to most significant, so the usual classroom program prints the array backwards. A bit-mask loop prints from the MSB without an explicit reversal.

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

8 people found this page helpful