# Bitwise Calculator

> AND/OR/XOR/NOT 與位移，2 進位／10 進位／16 進位同步顯示，8/16/32/64-bit 寬度，signed 與 unsigned 並排看，還有暫存器 bitfield 逐欄解碼，64-bit 一樣精確。

- URL: https://bytescope.dev/zh-Hant/bitwise-calculator/
- Locale: zh-Hant · Also: [en](https://bytescope.dev/en/bitwise-calculator.md) · [ja](https://bytescope.dev/ja/bitwise-calculator.md)
- Runs: 全部在你的瀏覽器裡跑，什麼都不會上傳。
- Requires: Any modern browser (Chrome, Edge, Firefox, Safari), desktop and mobile.
- Updated: 2026-09-08

## What it does

datasheet 開著，暫存器讀回來是 `0x3F80`，你要知道的只有一件事：每個欄位在說什麼。把值貼上來，欄位配置只寫一次——`reserved:1, mode:3, prescaler:4, enable:1, status:7`——每個欄位就會列出自己的位元範圍、原始 2 進位，以及 10 進位與 16 進位的值。配置存在你的瀏覽器裡，所以你翻 reference manual 第 412 頁時打進去的那組定義，下週還在。下次這個值出現在 log 裡，你兩秒就解完，不用在紙上一個 nibble 一個 nibble 數。

signed 與 unsigned 兩種讀法是並排放的，不是藏在切換鈕後面。`0xFF` 同時是 255 也是 −1，哪個才對完全看產生它的那段程式碼把變數宣告成什麼；抓錯邊是一整類 bug——把 −1 °C 報成 255 的感測器、看起來大到不合理的狀態欄位。兩欄同時看得到，這件事就從「你會犯的錯」變成「你能回答的問題」：unsigned 那欄是 65,535、signed 那欄是 −1，你就知道自己在看什麼了。

寬度不是裝飾。`1 << 40` 在 32-bit 是 0，在 64-bit 是 1,099,511,627,776；`NOT 0x0F` 在一個位元組裡是 `0xF0`，在一個 word 裡是 `0xFFFFFFF0`；負數右移的結果也要看它住在幾個位元裡。JavaScript 自己的 `<<`、`>>`、`&` 會在開算之前先把每個運算元砍成 32-bit，這就是一堆網頁計算機的 64-bit 答案默默算錯的原因——`1 << 31` 變成負數，超過 2^32 的東西直接歸零。這頁全部用 `BigInt` 算，算完才按你選的寬度做遮罩，所以 64-bit 的結果是精確的，8-bit 也會像真正的 `uint8_t` 那樣繞回去。

盯著螢幕上的 `0b0011_1111_1000_0000` 判斷 bit 7 有沒有立起來，正是凌晨兩點的人類最容易數錯的那種事。所以這裡有點得動的位元格網：每個 bit 都是一格、上面標著編號，點一下就翻，2 進位、10 進位、16 進位、signed 與 unsigned 的讀法，還有 bitfield 的逐欄解碼，全部一起更新。所有計算都在你的瀏覽器裡完成，這頁是靜態檔案，背後沒有 API——這點在這裡是真的有差：還沒發表的硬體，暫存器值本身就是機密，而你在逆推某顆 peripheral 時取的那些欄位名字，洩漏的資訊跟數字一樣多。

## Limits

Does not evaluate arbitrary programming expressions or floating-point math; it works on integers up to 64 bits and register bit fields.

## FAQ

### `>>` 和 `>>>` 差在哪裡？

`>>` 是算術位移：它會把符號位元複製到上面空出來的位元，符號因此保住，所以 `-8 >> 1` 是 `-4`，負的還是負的。`>>>` 是邏輯位移，上面一律補 0，同一組位元模式滑下來就變成一個很大的正數。值是正的時候兩者結果一樣，所以差別要等最高位元立起來才咬人。C 只有一個 `>>`，行為由型別決定——signed 走算術、unsigned 走邏輯——所以這頁把寬度和有沒有符號都攤在檯面上，不讓它靠猜。

### 為什麼 `1 << 31` 在 JavaScript 是負的，在這裡不是？

因為 JavaScript 的位元運算子會先把運算元轉成 32-bit 有號整數。`1 << 31` 立起 32-bit signed 的最高位元，也就是符號位元，所以印出來是 −2147483648；再往前一步，`1 << 32` 又回到 1，因為位移量會對 32 取餘數。這台計算機用 `BigInt` 算，算完才套上你選的寬度，所以 32-bit 時 unsigned 那欄是 2,147,483,648、旁邊擺著 −2,147,483,648；64-bit 的 `1 << 40` 是實實在在的 1,099,511,627,776，不是 0。

### 欄位配置要怎麼寫？

一個欄位一組 `name:width`，用逗號隔開：`status:4, error:1, reserved:3` 就是一顆 8-bit 的暫存器。順序照 datasheet 畫的那樣，從最高位元往下排，各欄寬度加起來要剛好等於你選的暫存器寬度——少了或爆了，工具會直接告訴你。不在意的空隙就用 `reserved:` 填掉；把它留在配置裡，下面那些欄位的位元位置才不會跑掉。每組存下來的配置都有自己的名字，所以同一顆晶片的 `CTRL1`、`STATUS`、`FIFO_CFG` 可以並排放著。

### 為什麼不叫我選 signed 或 unsigned，而是兩個都給？

因為你剛把值貼上來的那一刻，常常還不知道答案。從 serial dump 撈出來的一個位元組就只是八個位元；`0xFE` 是 254 還是 −2，取決於寫出它的那段程式碼，不是位元本身的性質。逼你先選，就是有一定機率選錯而且不會發現，因為兩種讀法單獨看都很合理。並排擺出來，`0xFE` 是 254 和 −2，哪個對得上物理量一眼就看出來——位元組數不會是負的，溫度會。

### 改位元寬度到底改了什麼？

改的是每個結果要套的遮罩，連帶改了符號位元的位置。8-bit 時 `0x1FF` 會被切成 `0xFF`、`NOT 0` 是 `0xFF`、signed 的讀法從 `0x80` 開始變負；64-bit 時同樣的運算保留全部 64 個位元，符號位元是 bit 63。位移也會跟著變，因為被推出寬度上緣的位元是直接丟掉、不會記著——`uint16_t` 暫存器對它們做的就是這件事。切換寬度之後，2 進位、16 進位、位元格網、bitfield 解碼，每一塊都會用新的寬度重算。

### 我輸入的值和存下來的配置會被上傳嗎？

不會。這頁是靜態檔案，計算全在你的瀏覽器裡完成，存下來的欄位配置放在瀏覽器的 `localStorage`，不會離開這台機器，也沒有帳號要登入。代價是它綁瀏覽器、綁使用者設定檔：清掉網站資料就沒了，你在筆電上定義的配置也不會出現在桌機上。所以真的不想再從 datasheet 打一遍的配置，自己留一份備份。
