1. 背景と目的
従来の2進ADCは、各段の残差増幅を正確に×2とすることが前提であり、アナログ誤差がビット化結果に直接影響しやすい。
これに対し、β展開(1 < β < 2)を用いると桁表現に冗長性(redundancy)が生まれ、多少のアナログ誤差をディジタル領域で吸収・補正できる。
本稿では、β進数表記の定義から2進表記への変換までを、実装容易な形で整理する。
2. 表記の定義([0,1) に正規化)
(1) β進表記
桁 ( d_k \in {0,1} ) とする。
x = Σ_{k=1..L} d_k · β^(−k)
(2) 2進小数 Nビット表記
x = Σ_{i=1..N} b_i · 2^(−i)
(3) 冗長性
同一の値 x に対し、複数の桁列 {d_k} が存在しうる。
→ この多重表現性が、誤差訂正やゲイン補償に有利となる。
3. 変換アルゴリズム(β→2進)
β展開の評価値を求め(Horner法)、それを2進に展開する。
数値安定性が高く、固定小数点実装にも適する。
手順A:β→2進変換(2段構成)
A-1:β評価(Horner法)
v ← 0
for k = 1 .. L:
v ← (v + d_k) / β
# 終了時:v = x
A-2:2進展開(Nビット)
for i = 1 .. N:
v ← 2 * v
b_i ← floor(v)
v ← v − b_i
# 結果:b_1 ... b_N
必要に応じて整数化:
Q = round(x * 2^N)
4. 桁数対応(L と N の関係)
β進展開の分解能:
Δβ ≈ β^(−L)
2進展開の分解能:
Δ2 ≈ 2^(−N)
損失なく変換する条件:
β^(−L) ≤ 2^(−N)
⇒ L ≥ N · log_β(2) = N · (ln2 / lnβ)
実装推奨値:
L = ceil(N · log_β(2) + G)
G = 1~2 (ガード桁)
5. 数値例
β = 1.5
d = {1, 0, 1, 1} (L=4)
β評価:
v = ((((0+1)/1.5 +0)/1.5 +1)/1.5 +1)/1.5 = 0.7037…
2進展開(N=3):
i=1: 2v=1.407 → b1=1, v=0.407
i=2: 2v=0.814 → b2=0, v=0.814
i=3: 2v=1.629 → b3=1, v=0.629
→ 結果:b = 101₂ ≈ 0.625
誤差は L を増やす/丸め制御で抑制できる。
6. 冗長桁の拡張
桁集合を {−1,0,1} などに拡張しても、手順A-1にそのまま代入可能。
後段(A-2)は同一。
→ 冗長性により一時的な誤差やゲインずれを吸収できる。
7. 実装指針(固定小数点)
- フォーマット:
Qm.n形式を使用(nはβ演算が飽和せず一貫性を保つだけ確保) - β,v,2v の演算におけるオーバーフローを防ぐ
- 乗除算は
β^−1の定数テーブルまたは CORDIC/シフト加算で代替可
推奨流れ:
d_k を逐次取り込み
→ (v + d_k) 加算
→ β で除算(または乗算×β^−1)
→ 2倍 → floor → 減算
Pythonコード
# ==========================================
# β進数列 → 2進展開 (Nビット)
# β=1.5, d=[1,0,1,1], N=10 固定例
# ==========================================
def beta_to_binary(beta, d, N=10):
# ---- A-1 β評価(Horner法)----
v = 0.0
for dk in d:
v = (v + dk) / beta
x = v # β展開による実数値
# ---- A-2 2進展開 ----
b = []
v = x
for i in range(N):
v *= 2
bi = int(v // 1) # floor(v)
b.append(bi)
v -= bi
# ---- 整数コード ----
Q = round(x * (2 ** N))
return b, x, Q
# ==== 固定パラメータ ====
beta = 1.5
d = [1, 0, 1, 1]
N = 10
# ==== 実行 ====
b, x, Q = beta_to_binary(beta, d, N)
# ==== 出力 ====
print("===== β→2進変換 結果 =====")
print(f"β = {beta}")
print(f"d = {d}")
print(f"評価値 x = {x:.10f}")
print(f"2進展開 b = {''.join(map(str,b))}")
print(f"整数コード Q = {Q}")
print(f"x ≈ {Q / (2**N):.10f}")