Terminal based bit manipulator in ncurses
bitwise is a handy tool for low level hackers, kernel developers and device driver developers: anyone who spends their day staring at a register dump wondering which bit is set.
&, |, ^, ~, >, *, /, %, +, -, with C's precedence.Pass a number and get every representation at once — signed and unsigned decimal, hexadecimal, octal, a human-readable size, Radix64, both IPv4 byte orders, and a labelled bit grid:
Or pass a whole C-style expression and let bitwise evaluate it first:
Run it with no arguments for the full-screen interactive mode.
| Platform | Install |
|---|---|
| Debian / Ubuntu 20.04+ | sudo apt-get install bitwise |
| Fedora | sudo dnf install bitwise |
| openSUSE | zypper install bitwise |
| Void | sudo xbps-install -S bitwise |
| Arch | AUR package |
| Snap | sudo snap install bitwise |
| Nix | nix-env -i bitwise |
| macOS (Homebrew) | brew install bitwise |
| macOS (MacPorts) | sudo port install bitwise |
| Buildroot / Yocto | In-tree; see their docs |
| Windows | From source, under mingw or msys2 |
Ubuntu older than 20.04
sudo add-apt-repository ppa:ramon-fried/bitwise
sudo apt-get update
sudo apt-get install bitwiseIn command line mode, bitwise calculates the given expression and prints the result in all bases, including the binary representation.
The base is detected from the prefix of the input: 0x/0X for hexadecimal, a leading 0 for octal, b for binary, and everything else is decimal. IPv4 addresses are parsed too, and are reported in both network and reversed byte order.
| Option | Meaning |
|---|---|
-i, --interactive |
Load interactive mode (the default when there is no input) |
-w, --width [b|w|l|d] |
Set bit width: byte (8), word (16), long (32) or double (64). Default: l |
-s, --si |
Print sizes using the SI standard (default: IEC) |
--no-color |
Start without color support |
-v, --version |
Output version information and exit |
-h, --help |
Display help and exit |
An expression starting with a minus sign would be taken for a command line option, so separate it
with --:
bitwise -- '-5'bitwise starts in interactive mode if no command line parameters are passed, or if the
-i | --interactive flag is given. Input a number, manipulate it, and watch the other bases change
as you go — including individual bits in the binary row. Press F1 for the help screen.
| Key | Action |
|---|---|
| ← ↓ ↑ → or h j k l | Move around |
| space | Toggle the bit under the cursor |
| w / b | Jump one byte forward / backward |
| F1 | Show the help screen |
| q | Quit |
| Key | Action |
|---|---|
| ~ | NOT |
| r | Reverse endianness |
| < / > | Shift left / right |
| ! @ $ * | Set the width to 8, 16, 32 or 64 bit |
[!WARNING] When changing the bit width, the number is masked with the new width, so you might lose precision. Use with care.
Enter the expression calculator by typing : (just like in vim), and leave it with ESC. Anything you type there is evaluated; the result is printed in the history window and also shown in binary and the various bases at the top.
The expression syntax is a subset of C, plus Verilog's bit select (below). These operators are supported, in order of precedence, tightest binding first:
| Precedence | Operators | Notes |
|---|---|---|
| 1 | ! ~ - + |
unary, right associative |
| 2 | * / % |
|
| 3 | + - |
|
| 4 | > |
|
| 5 | & |
|
| 6 | ^ |
|
| 7 | | |
Parentheses group as usual, and multiplication can be written implicitly: 2(3) and (2)(3) both
give 6.
This is the same ordering a C compiler uses, so an expression lifted out of source evaluates to the same thing here.
One difference from C: &=, ^= and |= are accepted, but there is nothing to assign to, so they
evaluate exactly like &, ^ and |.
Not supported: comparison and equality (`` = == !=), logical && and ||, the
ternary ?:, and exponentiation.
Fields can be pulled out with Verilog's notation, the same way a datasheet writes them:
| Expression | Meaning |
|---|---|
v[msb:lsb] |
The bits from msb down to lsb |
v[bit] |
A single bit |
bitwise '0x875423[31:23]'
bitwise '0x875423[15]'The field comes back right-aligned, as it does in Verilog and as a datasheet means it — not
masked in place. So 0xdeadbeef[31:16] is 0xdead, not 0xdead0000, and reading a field no longer
means working out its mask by hand:
0xdeadbeef[31:16] instead of (0xdeadbeef >> 16) & 0xffffThe indices are ordinary expressions, so v[15 + 16:16] works, and a slice is itself a value, so it
can be sliced or combined further. Both indices must fit the 64-bit value and msb must not be
below lsb; anything else is reported rather than quietly returning zero.
This is the one place the syntax is not C's — in C, v[3] would be array indexing. It is deliberate,
and it is the notation the registers being decoded are documented in.
$ symbol.BIT(x).$ |= BIT(n), $ &= ~BIT(n), $ ^= BIT(n) and $ & BIT(n).| Command | Action |
|---|---|
h(elp) |
Show the help screen |
c(lear) |
Clear the history window |
w(idth) [8 | 16 | 32 | 64] |
Set the required width mask |
o(utput) [dec(imal) | hex(adecimal) | oct(al) | bin(ary) | all] |
Set the default output for results |
q(uit) |
Exit |
vim-bitwise runs bitwise on the number under your cursor, without leaving the editor.
Rest the cursor on a numeric literal and its representations appear beside it. There is also an
operator, so biw runs bitwise on the word under the cursor and bi( on the
expression inside the parentheses, plus a :Bitwise command for anything you want to type out.
Hexadecimal, binary, octal and decimal literals are all recognised, including digit separators and
size suffixes such as 0xFF_u8.
Install it with your plugin manager:
-- lazy.nvim. Not lazy-loaded on a key: the hover is driven by an autocmd.
{ "mellowcandle/vim-bitwise", lazy = false }" vim-plug
Plug 'mellowcandle/vim-bitwise'It needs this bitwise binary on your $PATH, which you have already installed if you are reading
this. See the plugin's README for configuration and :checkhealth bitwise if anything looks wrong.
Ubuntu / Debian
sudo apt-get install build-essential
sudo apt-get install libncurses5-dev
sudo apt-get install libreadline-dev
sudo apt-get install libcunit1-devmacOS
brew install automake
brew install autoconf
brew install readline
brew install cunit
export LDFLAGS="-L$(brew --prefix readline)/lib -L$(brew --prefix cunit)/lib"
export CPPFLAGS="-I$(brew --prefix readline)/include -I$(brew --prefix cunit)/include"Download the latest release, then:
tar xfz RELEASE-FILE.TAR.GZ
cd RELEASE-DIR
./configure
make
sudo make installRun the unit tests with:
make check./bootstrap.sh.See CONTRIBUTING.md for the style, testing and commit conventions patches are expected to follow.
GPL-3.0-or-later. See LICENSE.
No open issues yet, or sync has not completed.