Motivation
Naively forcing $0$ to be invertible explodes algebra (you’ll derive $1=0$). But we still want a way to carry information at division-by-zero points (e.g., residues of poles) through computations. The trick: work in a ring that is ordinary on the surface but has a built-in, harmless “tag” for the singular part.
That tag is a nilpotent $\\kappa$ with $\\kappa^{N+1}=0$. For $N=1$ (dual numbers) every value is $a_b := a + b\\kappa$. The coefficient $b$ is your “remnant”.
Axioms (Order 1: Dual Numbers)
- Algebra. Work over field $F$ (usually $\\mathbb{R}$ or $\\mathbb{C}$). Adjoin central nilpotent $\\kappa$ with $\\kappa^2=0$. Elements are $a+b\\kappa$.
- Totalized division by zero. Define a linear operator $\\delta(x)=x\\kappa$ and set $$\\boxed{x/0 := \\delta(x) = x\\kappa}$$ In particular, $a/0=0_a$ and, by linearity, $0/0=0$.
- Projections. $\\mathrm{Re}(a+b\\kappa)=a$, $\\mathrm{Res}(a+b\\kappa)=b$. Product rule: $$\\mathrm{Res}(xy)=\\mathrm{Re}(x)\\,\\mathrm{Res}(y)+\\mathrm{Re}(y)\\,\\mathrm{Res}(x).$$
- Inverses (ordinary division). If $\\mathrm{Re}(y)\\neq 0$, then $y^{-1}$ exists and $x/y=x\\cdot y^{-1}$.
- Powers. $(a_b)^n=(a^n)_{n a^{n-1} b}$ for $n\\in\\mathbb{N}$.
All ring laws hold: associativity, commutativity, distributivity, and $x\\cdot 0=0$.
Examples
5_3 * 2 => 10_6
5_3 * 0 => 0_0
5/0 + 5/0 => 0_10
Res(5_3) => 3
(a_b)(c_d) => (ac)_(ad+bc)
Why the naive route collapses
If you keep associativity and also insist $0\\cdot(1/0)=1$, then for any $y$:
$y = y\\cdot 1 = y\\cdot (0\\cdot(1/0)) = (y\\cdot 0)\\cdot(1/0) = 0\\cdot(1/0)=1$, contradiction.
Our model avoids this by not making $0$ invertible; we only define a separate total operator $x/0 := x\\kappa$ and keep $x\\cdot 0=0$.
Evaluating at Poles (Simple Case)
Let $f(x)=\\dfrac{p(x)}{q(x)}$ and $x_0$ be a simple pole: $q(x_0)=0,\\ q'(x_0)\\neq0$. Write $f(x)=\\dfrac{R}{x-x_0} + \\text{(regular)}$ with residue $R=\\dfrac{p(x_0)}{q'(x_0)}$. Define the DBZ value $$\\boxed{f(x_0)^{\\mathrm{DBZ}} = A_{\\,R} = A + R\\kappa}$$ where the finite part $$A=\\lim_{x\\to x_0}\\Big(f(x)-\\frac{R}{x-x_0}\\Big) = \\frac{p'(x_0)q'(x_0)-\\tfrac12 p(x_0)q''(x_0)}{(q'(x_0))^2}.$$
For higher-order poles, use order-$N$ DBZ ($\\kappa^{N+1}=0$) and store successive principal-part coefficients in $\\kappa^m$.
Relation to Known Frameworks
Framework | Idea | Pros | Cons |
---|---|---|---|
Dual / Jet numbers | Adjoin nilpotent(s) $\\kappa$ | Preserves ring laws; great for AD and finite-part bookkeeping | Not a field; $0$ not invertible |
Meadows | Totalized field with $0^{-1}=0$ | Equationally compact | Different semantics; doesn’t carry “residue” data by default |
Wheels / Transreals | Add special values ($\\infty$, NaNs) | Total operations possible | Arithmetic laws change; less fine-grained local data |
Play: Order-1 DBZ Calculator (runs in your browser)
Enter numbers as a_b
or plain a
. Operations use the rules above, with $x/0 := x\\kappa$.
Key Properties (sketches)
- Linearity of $/0$. From definition: $(x+y)/0=(x+y)\\kappa=x\\kappa+y\\kappa=x/0+y/0$.
- Product rule. $(xy)/0=(xy)\\kappa=x(y\\kappa)+y(x\\kappa)$.
- $0/0=0$. $0/0=0\\cdot\\kappa=0$ by linearity.
- Ring laws. Inherited from $F[\\kappa]/(\\kappa^2)$ (commutative, associative, distributive).
- Inverse when $\\mathrm{Re}(y)\\neq0$. Solve $(a+b\\kappa)(\\alpha+\\beta\\kappa)=1$ to get $\\alpha=\\tfrac1a$, $\\beta=-\\tfrac{b}{a^2}$.
Python: Minimal Library
Install-free: copy into dbz.py
.
from typing import Iterable, Tuple, List
class DBZ:
__slots__=("N","c")
def __init__(self, coeffs: Iterable[float], N:int|None=None):
coeffs=list(coeffs); N=len(coeffs)-1 if N is None else int(N)
self.N=N; c=list(coeffs[:N+1]); c += [0.0]*((N+1)-len(c)); self.c=c
@staticmethod
def real(a:float,N:int=1): return DBZ([float(a)]+[0.0]*N,N)
@staticmethod
def tag(b:float,N:int=1): return DBZ([0.0,float(b)]+[0.0]*(N-1),N)
def __repr__(self): return f"{self.c[0]}_{self.c[1]}" if self.N==1 else self.to_string("poly")
def to_string(self,style="poly"):
terms=[];
for i,ci in enumerate(self.c):
if abs(ci)<1e-15: continue
terms.append(f"{ci}" if i==0 else (f"{ci}*k" if i==1 else f"{ci}*k^{i}"))
return " ".join(t if t==terms[0] else "+ "+t for t in terms) if terms else "0"
def _pair(self,y):
N=max(self.N,y.N); return DBZ(self.c,N), DBZ(y.c,N), N
def __add__(self,y): x,y,N=self._pair(y); return DBZ([x.c[i]+y.c[i] for i in range(N+1)],N)
def __sub__(self,y): x,y,N=self._pair(y); return DBZ([x.c[i]-y.c[i] for i in range(N+1)],N)
def __mul__(self,y):
x,y,N=self._pair(y); out=[0.0]*(N+1)
for i in range(N+1):
xi=x.c[i]
if abs(xi)<1e-18: continue
for j in range(N+1-i): out[i+j]+=xi*y.c[j]
return DBZ(out,N)
def __rmul__(self,k:float): return DBZ([float(k)*ci for ci in self.c], self.N)
def mul_k(self): return DBZ([0.0]+self.c[:-1], self.N)
def __truediv__(self,y):
x,y,N=self._pair(y)
if all(abs(ci)<1e-18 for ci in y.c): return x.mul_k() # x/0 := x*k
if abs(y.c[0])>1e-18: return x * y.inv() # ordinary division
raise ZeroDivisionError("Denominator has zero real part.")
def Re(self): return self.c[0]
def Res(self,order:int=1): return self.c[order] if 1<=order<=self.N else 0.0
def inv(self):
if abs(self.c[0])<1e-18: raise ZeroDivisionError("Inverse needs nonzero real part.")
N=self.N; a=self.c; z=[0.0]*(N+1); z[0]=1.0/a[0]
for n in range(1,N+1):
s=0.0
for i in range(1,n+1): s += a[i]*z[n-i]
z[n] = -s/a[0]
return DBZ(z,N)
def parse_ab(s:str,N:int=1):
s=s.strip()
if "_" in s: a,b=s.split("_",1); return DBZ([float(a),float(b)],N)
return DBZ.real(float(s),N)
def dby0(a:float,N:int=1): return DBZ.tag(a,N)
CLI (menu)
from dbz import DBZ, parse_ab, dby0
# see repo for dbz_cli.py; supports + - * /, x/0, powers, inv, Re, Res
Applications & Limits
- Applications: symbolic pipelines that must carry principal parts; automatic differentiation analogies; clean evaluation at simple poles; didactic exploration of totalized operations.
- Limits: this doesn’t make $0$ invertible; it doesn’t replace distributions/renormalization in physics. It complements them by tracking finite parts/residues algebraically.
FAQ
Is $2_0$ the same as $2$? Yes. Coefficients live in $F$; our operator is linear, so $0/0=0$ here and $2_0=2$.
Why is $5_3\\cdot 0=0$? To preserve ring laws; read the remnant with $\\mathrm{Res}$.
Can I track higher-order poles? Yes—use order $N>1$ (jet numbers) so $\\kappa^{N+1}=0$.
What’s actually new? The algebra is classical; the contribution is a clean, total $/0$ semantics with practical computation rules and code.
Cite & License
MIT License. Cite as: DBZ Algebra: Totalized Division by Zero via Nilpotent Extensions — Barwhoom (2025). GitHub: DivisionByZeroAxiom/dbz-algebra-site
.