# How to Format Binary Integers with fmtlib: A Complete Guide to Binary Formatting in C++

> Master binary formatting in C++ with fmtlib. Learn to convert integers to base-2 using b and B specifiers for width, alignment, and prefix control. A complete guide.

- Repository: [Hello World Foundation/fmt](https://github.com/fmtlib/fmt)
- Tags: how-to-guide
- Published: 2026-09-06

---

**Yes, {fmt} supports binary integer formatting natively using the `b` or `B` format specifier, which converts any integral type to its base-2 representation with full control over width, alignment, and prefix.**

Binary formatting is a built-in capability of the {fmt} library, implemented directly in its core formatting engine. This guide covers how to use binary specifiers, the internal implementation, and practical examples drawn from the official source code.

---

## Binary Format Specifiers

{fmt} recognizes **`b`** (lowercase) and **`B`** (uppercase) as presentation types for binary output. In [`include/fmt/base.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/base.h), the library defines `presentation_type::bin` to represent this formatting mode (lines 1548–1566). The parser in [`include/fmt/format.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h) handles the `'b'` case during format string analysis, routing integer arguments through the binary conversion path.

The binary formatter supports the same modifiers as other numeric types:

- **`#`** — alternate form, prepends `0b` to the output
- **width** — minimum field width for padding
- **fill/alignment** — left (`<`), right (`>`), or center (`^`) alignment with custom fill characters
- **sign** — plus (`+`), minus (`-`), or space (` `) for signed types

---

## Basic Binary Formatting Examples

The following code demonstrates core binary formatting patterns:

```cpp
#include <fmt/format.h>
#include <iostream>

int main() {
  int v = 42;

  // Simple binary output
  std::cout << fmt::format("{:b}\n", v);          // 101010

  // Upper-case specifier (identical output)
  std::cout << fmt::format("{:B}\n", v);          // 101010

  // Alternate form adds "0b" prefix
  std::cout << fmt::format("{:#b}\n", v);         // 0b101010

  // Width and fill (right-aligned, space-padded)
  std::cout << fmt::format("{:8b}\n", v);         //   101010

  // Zero-fill with width
  std::cout << fmt::format("{:0>8b}\n", v);       // 00101010

  // Left-aligned with width
  std::cout << fmt::format("{:<8b}\n", v);        // 101010  

  // Unsigned integer formatting
  unsigned int u = 255;
  std::cout << fmt::format("{:#b}\n", u);         // 0b11111111
}

```

Key observations from these examples:

- **`{:b}`** produces the minimal binary representation without padding
- **`{:#b}`** adds the `0b` prefix via the alternate form flag
- **Width specifiers** combine seamlessly with binary output, using the same syntax as decimal or hexadecimal formatting
- Both signed and unsigned integers are supported

---

## Internal Implementation

The binary formatting pipeline follows the standard {fmt} architecture:

**[`include/fmt/base.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/base.h)** (lines 1548–1566)

Defines `presentation_type::bin` as the internal enum value for binary formatting. The library maps both `'b'` and `'B'` input characters to this single presentation type.

**[`include/fmt/format.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h)** (parse stage)

The format specifier parser recognizes the binary case and populates the format specification with `presentation_type::bin`. This occurs during compile-time parsing for `FMT_COMPILE` strings or runtime for dynamic format strings.

**[`include/fmt/chrono.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/chrono.h)** (line 683)

Shows binary handling extending to chrono types, where duration values can also be formatted with binary specifiers.

The actual binary conversion uses optimized bit-extraction routines that operate directly on the argument's underlying value, avoiding temporary string allocations or external dependencies.

---

## Advanced Binary Formatting Patterns

### Combined Specifiers

Multiple formatting options can be combined in a single format string:

```cpp
#include <fmt/format.h>
#include <iostream>

int main() {
  int value = 13;  // 1101 in binary

  // Center-aligned with fill, plus sign, and alternate form
  std::cout << fmt::format("{:*^+12#b}\n", value);
  // Output: **+0b1101***
  
  // Explanation of components:
  // *    - fill character
  // ^    - center alignment
  // +    - always show sign
  // 12   - minimum width
  // #    - alternate form (0b prefix)

  // b    - binary presentation type
}

```

### Batch Formatting

Binary formatting integrates with {fmt}'s argument handling for multiple values:

```cpp
#include <fmt/format.h>
#include <bitset>
#include <iostream>

int main() {
  // Format multiple integers with binary
  std::cout << fmt::format("flags: {:08b} {:08b} {:08b}\n", 5, 170, 255);
  // Output: flags: 00000101 10101010 11111111

  // Mixed format bases in single call
  std::cout << fmt::format("dec={:d} hex={:#x} bin={:#b}\n", 42, 42, 42);
  // Output: dec=42 hex=0x2a bin=0b101010
}

```

---

## Performance Characteristics

Binary formatting in {fmt} shares the performance profile of other built-in presentation types:

- **Compile-time validation** — format strings are checked at compile time when using `FMT_STRING` or `fmt::format_string`
- **Type safety** — only integral types accept binary specifiers; floating-point or string arguments trigger compile errors
- **No heap allocation** — small binary outputs use the library's internal buffer; larger outputs use optimized memory management
- **Vectorized conversion** — the binary digit extraction uses bitwise operations rather than division loops

---

## Comparison with Standard Alternatives

| Approach | Syntax | Prefix Control | Performance |
|----------|--------|---------------|-------------|
| **{fmt} binary** | `fmt::format("{:#b}", 42)` | Built-in (`#` flag) | Optimized, type-safe |
| `std::bitset` | `std::bitset<8>(42).to_string()` | Manual concatenation | Fixed width, runtime size |
| Manual conversion | Custom loop | Full control | Error-prone, verbose |
| `std::to_chars` | `std::to_chars(buf, end, 2)` | None | C++17, binary base not standard |

---

## Summary

- **{fmt} implements binary formatting natively** via the `b` and `B` specifiers, mapped internally to `presentation_type::bin`
- The feature is located in [`include/fmt/base.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/base.h) and [`include/fmt/format.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h), with full support for width, alignment, fill, and alternate form
- **Use `{:#b}`** to include the `0b` prefix, and combine with standard numeric formatting options
- Binary formatting achieves the same performance and type safety as decimal or hexadecimal output
- Chrono durations also support binary specifiers as shown in [`include/fmt/chrono.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/chrono.h)

---

## Frequently Asked Questions

### Does fmtlib support uppercase binary output with 0B prefix?

**Capital `B` in the format specifier changes only the presentation type character识别；both `b` and `B` produce identical digit output (0s and 1s).** The alternate form `#` always produces lowercase `0b` regardless of specifier case. For `0B` prefix, manual string manipulation is required: `fmt::format("0B{:B}", value)`.

### Can I format floating-point numbers in binary with fmtlib?

**No, binary specifiers are restricted to integral types.** Attempting `fmt::format("{:b}", 3.14)` produces a compile-time error. The library's type system enforces this constraint through `detail::is_integral<T>` checks in the formatting pipeline.

### How do I right-align binary output with zero-padding?

**Use the `0` fill character combined with right alignment:** `fmt::format("{:0>16b}", value)` produces zero-padded 16-bit output. Alternatively, the simpler `{:016b}` syntax achieves the same result when left alignment is not required.

### Is binary formatting available in C++20 std::format?

**Yes, C++20 `std::format` adopted {fmt}'s binary specifiers.** The `b`, `B`, and `#b` patterns work identically in standard library implementations that support C++20 format. However, {fmt} typically provides broader compiler support and additional performance optimizations not yet present in all standard library implementations.