# Fixed-Math-Taylor
[](https://crates.io/crates/fixed-math-taylor)
[](https://docs.rs/fixed-math-taylor)
[](https://www.gnu.org/licenses/gpl-2.0.html)
A lightweight, zero-dependency fixed-point trigonometry library optimized for embedded systems and microcontrollers without a floating-point unit (FPU).
## Version 0.4.0 uses #![forbid(unsafe_code)] For safety
⚠️ Security Note (v0.3.4)IMPORTANT: Please do not use versions prior to 0.3.4.Earlier versions contained an integer overflow bug in the Taylor engine when approaching 90° ($PI/2$).Fixed in v0.3.4:Internal calculations upgraded to i64 to prevent overflows.Added Arithmetic Saturation (clamping) to ensure results stay within [-32767, 32767].Verified on RP2350(Raspberry Pi Pico 2) hardware.
## Overview
Fixed-Math-Taylor eliminates the computational overhead of software floating-point emulation on resource-constrained devices by implementing trigonometric functions using **pure integer arithmetic** and **bit shifts**. Designed specifically for the RP2040 and similar microcontrollers, it delivers production-ready performance with multiple calculation engines to suit different use cases.
### Performance Advantage
- **No FPU emulation overhead**: Uses only integer operations (no f32/f64 soft math)
- **Deterministic execution**: No floating-point rounding surprises
- **Minimal code size**: Optimized to ~1-2KB with single engine
- **Embedded-friendly**: `#![no_std]` compatible, zero allocations
## Installation
Add to your `Cargo.toml`:
```toml
[dependencies]
fixed-math-taylor = { version = "0.3.3", features = ["lut"] }
```
Choose one calculation engine via features:
- `lut` – Lookup table + interpolation (recommended for most cases)
- `taylor` – Pure algorithmic Taylor series
- `fast-sin` – Ultra-fast Bhaskara I approximation
## Quick Start
```rust
use fixed_math_taylor::{sin_fixed, cos_fixed, Angle, Fixed};
fn main() {
// Angle: 0 to 65535 represents 0 to 2π
let angle: Angle = 16384; // This is π/2
// Results are in Q15 fixed-point format
// 32767 ≈ 1.0, -32768 ≈ -1.0
let sin_value: Fixed = sin_fixed(angle);
let cos_value: Fixed = cos_fixed(angle);
// Convert to regular float for display/use
let sin_f32 = (sin_value as f32) / 32767.0;
let cos_f32 = (cos_value as f32) / 32767.0;
println!("sin(π/2) ≈ {:.4}", sin_f32); // Output: 1.0000
println!("cos(π/2) ≈ {:.4}", cos_f32); // Output: ~0.0000
}
```
## Number Formats
### Q15 Fixed-Point Output
All trigonometric functions return `Fixed` (i16) in Q15 format:
| 32767 | +1.0 |
| 16384 | +0.5 |
| 0 | 0.0 |
| -16384 | -0.5 |
| -32768 | ≈-1.0 |
Conversion formula:
```rust
let value_f32 = (fixed_value as f32) / 32767.0;
```
### Angle Input (u16)
Angles use a full 16-bit range for 2π:
| 0 | 0 |
| 16384 | π/2 |
| 32768 | π |
| 49152 | 3π/2 |
| 65535 | ≈2π |
## Calculation Engines
### 1. LUT (Lookup Table) – `features = ["lut"]`
**Recommended for most applications.**
- **Method**: 257-entry lookup table + linear interpolation
- **Precision**: ~0.1% error
- **Speed**: Fastest (2-3 CPU cycles)
- **Memory**: 640 bytes Flash
- **Best for**: Motor control, audio synthesis, PID loops, real-time systems
Uses quadrant symmetry to minimize Flash footprint while maintaining high accuracy through interpolation.
```rust
use fixed_math_taylor::{sin_fixed, cos_fixed, sin_cos};
let angle = 16384;
let s = sin_fixed(angle);
let c = cos_fixed(angle);
// Combined sin/cos (slightly faster than calling both)
let (s, c) = sin_cos(angle);
```
### 2. Taylor Series – `features = ["taylor"]`
**Pure algorithmic approach.**
- **Method**: 5th-order Taylor expansion in Q15
- **Precision**: High (0.01% error)
- **Speed**: Fast (10-15 CPU cycles)
- **Memory**: ~500 bytes Flash (no runtime table)
- **Best for**: Algorithm-only designs, scenarios where Flash preservation is critical
```rust
#[cfg(feature = "taylor")]
use fixed_math_taylor::taylor_impl;
let angle = 16384;
let s = taylor_impl::sin_taylor(angle);
let c = taylor_impl::cos_taylor(angle);
```
### 3. Fast-Sin (Bhaskara I) – `features = ["fast-sin"]`
**Maximum speed with acceptable precision.**
- **Method**: Bhaskara I approximation formula
- **Precision**: Medium (~0.5% error)
- **Speed**: Fastest (1-2 CPU cycles)
- **Memory**: ~300 bytes Flash
- **Best for**: Graphics, animations, scenarios where ultra-high precision isn't needed
```rust
#[cfg(feature = "fast-sin")]
use fixed_math_taylor::fast_impl;
let angle = 16384;
let s = fast_impl::sin_fast(angle);
let c = fast_impl::cos_fast(angle);
```
## Feature Comparison Table
| `lut` | Table + Interp | ~0.1% err | ⚡⚡⚡ | 640 B | Control, audio, motors |
| `taylor` | Taylor Series | ~0.01% err | ⚡⚡ | 500 B | Pure algorithms |
| `fast-sin` | Bhaskara I | ~0.5% err | ⚡⚡⚡⚡ | 300 B | Graphics, animations |
## Typical Use Cases
### Motor Control & PID Loops
Use **LUT engine** (`features = ["lut"]`). The 0.1% precision is more than sufficient for control loops, and the speed is optimal for real-time systems.
### Audio Synthesis
Use **LUT engine**. Linear interpolation provides smooth curve generation without aliasing issues.
### Graphics & Game Development
Use **Fast-Sin engine** (`features = ["fast-sin"]`). The speed advantage justifies the lower precision for visual effects.
### Precise Numerical Algorithms
Use **Taylor engine** (`features = ["taylor"]`). Pure algorithmic computation without Flash tables.
## Embedded Integration Example
### RP2040 (Raspberry Pi Pico)
```rust
#![no_std]
#![no_main]
use fixed_math_taylor::sin_fixed;
#[entry]
fn main() -> ! {
// Your initialization code...
loop {
// Generate a smooth sine wave for PWM output
for angle in (0..65536).step_by(256) {
let sample = sin_fixed(angle as u16);
// Use `sample` to drive PWM or other outputs
}
}
}
```
## Technical Details
### Q15 Arithmetic
Q15 is a 16-bit signed fixed-point format where:
- The sign bit is separate (bit 15)
- Bits 14-0 represent the fractional part
- Maximum value: 32767 ≈ 1.0
- Minimum value: -32768 ≈ -1.0
**Why Q15?**
- Perfect fit for 16-bit microcontroller ALUs
- Provides 15-bit precision (0.003% resolution)
- Single 16×16→32 multiply operation (standard ALU feature)
### Quadrant Symmetry Optimization
The LUT engine exploits trigonometric symmetry to reduce memory:
- Stores only first quadrant (0 to π/2): 257 points
- Uses symmetry properties for quadrants 2-4
- Linear interpolation ensures smooth transitions between table points
- Total: 640 bytes vs. 1KB+ for naive full table
### Overflow Prevention
Internal intermediate calculations use 64-bit registers when necessary to prevent overflow while maintaining the speed of 32-bit arithmetic.
## Testing & Validation
Comprehensive test suite validates:
- Mathematical accuracy across all quadrants
- Sign correctness near π and 2π boundaries
- Interpolation consistency (LUT engine)
- Taylor expansion coefficients (Taylor engine)
Run tests:
```bash
cargo test --all-features
```
## License
Copyright © 2026 Jorge Andre Castro
This is distributed under the **GNU General Public License v2.0 or later**. All derivative code must remain free and open source.
See [LICENSE](LICENSE) for full details.
## Performance Benchmarks
Typical execution times on RP2040 (125 MHz):
| LUT | 2.4 µs | 2.4 µs | 3.5 µs |
| Taylor | 12.8 µs | 12.8 µs | 24 µs |
| Fast-Sin | 1.6 µs | 1.6 µs | 3.2 µs |
*(Approximate; varies with compiler optimizations)*
## Contributing
Found a bug or have a suggestion? Please open an issue or pull request on [GitHub](https://github.com/jorgeandrecastro/fixed-math-taylor).
## Future Enhancements
Planned additions:
- Tangent function (tan)
- Inverse trigonometric functions (arcsin, arccos)
- Additional engine optimizations for ARM Cortex-M0+ and M4
---
**Built for speed and efficiency on resource-constrained systems.**