mirror of
https://github.com/metabarcoding/obitools4.git
synced 2026-04-30 12:00:39 +00:00
83 lines
3.9 KiB
Markdown
83 lines
3.9 KiB
Markdown
|
|
# `obifp`: Semantic Overview of Public API
|
|||
|
|
|
|||
|
|
The `obifp` package provides a family of fixed-size, arbitrary-precision unsigned integer types—`Uint64`, `Uint128`, and `Uint256`—designed for high-precision arithmetic where overflow safety, bitwise control, and type consistency are critical (e.g., cryptography, genomics with OBITools). All types share a unified interface (`FPUint[T]`) and enforce strict correctness via panics on overflow/underflow or division-by-zero.
|
|||
|
|
|
|||
|
|
## Core Principles
|
|||
|
|
|
|||
|
|
- **Explicit precision**: No silent truncation; narrowing casts emit warnings (via `obilog.Warnf`).
|
|||
|
|
- **Panic-on-error semantics**: Arithmetic operations (`Add`, `Sub`, `Mul`, etc.) panic on overflow/underflow.
|
|||
|
|
- **Bit-level fidelity**: Shifts and bitwise operations operate across full bit-width with carry propagation.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Unified Interface: `FPUint[T]`
|
|||
|
|
|
|||
|
|
All three types (`Uint64`, `Uint128`, `Uint256`) implement this generic interface:
|
|||
|
|
|
|||
|
|
- **Construction & Initialization**
|
|||
|
|
- `Zero() T`: Returns the additive identity.
|
|||
|
|
- `Set64(v uint64) T`: Initializes from a native 64-bit value (zero-extended).
|
|||
|
|
- `OneUint[T]`: Helper to construct the value *1*.
|
|||
|
|
|
|||
|
|
- **Downcasting & Utility**
|
|||
|
|
- `AsUint64() uint64`: Extracts the least-significant limb (assumes higher limbs are zero; warns if not).
|
|||
|
|
- `IsZero() bool`: Checks for equality with zero.
|
|||
|
|
|
|||
|
|
- **Logical & Bitwise Operations**
|
|||
|
|
- `And(v T)`, `Or(v T)`, `Xor(v T)` — bitwise logic between two values of same type.
|
|||
|
|
- `Not() T` — inverts all bits (two’s complement style for unsigned).
|
|||
|
|
- `LeftShift(n uint) T`, `RightShift(n uint) T` — multi-limb shifts with carry handling; warns if shift ≥ full bit-width.
|
|||
|
|
|
|||
|
|
- **Arithmetic**
|
|||
|
|
- `Add(v T)`, `Sub(v T)` — with carry/borrow propagation; panics on overflow/underflow.
|
|||
|
|
- `Mul(v T)` — full-width multiplication (uses hardware-optimized limb-wise ops); panics on overflow.
|
|||
|
|
- *Division (`Div`, `Mod`) is implemented only for concrete types (see below).*
|
|||
|
|
|
|||
|
|
- **Comparison**
|
|||
|
|
- `Cmp(v T) int` — returns `-1`, `0`, or `+1`.
|
|||
|
|
- Overloaded operators: `<`, `<=`, `>`, `>=` (all returning `bool`).
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Concrete Types & Specialized Features
|
|||
|
|
|
|||
|
|
### ✅ `Uint64`
|
|||
|
|
- Native Go `uint64` wrapper with strict overflow checking.
|
|||
|
|
- Uses `math/bits.Add64`, `Mul64` internally for correctness.
|
|||
|
|
- Supports conversion to larger types: `Uint128()`, `Uint256()`.
|
|||
|
|
|
|||
|
|
### ✅ `Uint128`
|
|||
|
|
- Internally: two limbs (`w0`, `w1`).
|
|||
|
|
- **Arithmetic**:
|
|||
|
|
- Full support: `Add(v)`, `Sub(v)`, `Mul(v)` (128×128), and scalar variants: `Add64`, `Mul64`.
|
|||
|
|
- Division & Modulo:
|
|||
|
|
- `Div(v)`, `Mod(v)` — integer division with remainder.
|
|||
|
|
- `QuoRem(v Uint128) (q, r Uint128)` — combined quotient/remainder.
|
|||
|
|
- `Div64`, `Mod64` for division by 64-bit scalar.
|
|||
|
|
- **Bitwise**: Full support (`And`, `Or`, `Xor`, `Not`), plus shifts.
|
|||
|
|
- **Conversion**:
|
|||
|
|
- Safe upcast to `Uint256`.
|
|||
|
|
- Downcast to `uint64` via `AsUint64()` (warns if high limb ≠ 0).
|
|||
|
|
|
|||
|
|
### ✅ `Uint256`
|
|||
|
|
- Internally: four limbs (`w0` to `w3`) — supports values up to $2^{256} - 1$.
|
|||
|
|
- **Arithmetic**:
|
|||
|
|
- `Add(v)`, `Sub(v)` — limb-wise with carry/borrow.
|
|||
|
|
- `Mul(v)` — schoolbook multiplication across limbs; panics on overflow.
|
|||
|
|
- `Div(v)`: Long division implementation (repeated subtraction of shifted multiples); panics on zero divisor.
|
|||
|
|
- **Shifts**: Multi-limb shifts with carry propagation across all limbs.
|
|||
|
|
- **Conversion**:
|
|||
|
|
- Downcast to `Uint128()` / `AsUint64()`, with overflow warnings.
|
|||
|
|
- Upcast from smaller types via implicit zero-extension.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Helper Functions (Generic)
|
|||
|
|
|
|||
|
|
- `ZeroUint[T FPUint[T]]() T`: Returns zero for type parameter.
|
|||
|
|
- `From64[T FPUint[T]](v uint64) T`: Converts native 64-bit to typed value.
|
|||
|
|
|
|||
|
|
All operations are **value-returning** (no in-place mutation), enabling fluent chaining and immutability.
|
|||
|
|
|
|||
|
|
> ⚠️ **Design Note**: Division methods are *not* part of the generic `FPUint[T]` interface (commented out), but are implemented concretely for each type. This reflects performance/complexity trade-offs and leaves room to extend later.
|