A powerful and flexible Swift library for formatting numbers using engineering notation with SI metric prefixes. Supports all multiples of 3 SI metric prefixes from quecto (10⁻³⁰) to quetta (10³⁰).
- ✅ Complete SI Prefix Support: All 20 standard metric prefixes
- ✅ High Precision: Full
Decimaltype support for exact arithmetic - ✅ Thread Safe:
Sendableconformance for concurrent environments - ✅ Locale Aware: Respects decimal separators and number formatting rules
- ✅ Highly Configurable: Fraction digits, spacing, micro symbol options
- ✅ Swift 6 Ready: Uses modern Swift Testing framework
- ✅ Zero Dependencies: Lightweight with no external dependencies
| Prefix | Symbol | Factor | Example |
|---|---|---|---|
| quetta | Q | 10³⁰ | 1Q = 1,000,000,000,000,000,000,000,000,000,000 |
| ronna | R | 10²⁷ | 1R = 1,000,000,000,000,000,000,000,000,000 |
| yotta | Y | 10²⁴ | 1Y = 1,000,000,000,000,000,000,000,000 |
| zetta | Z | 10²¹ | 1Z = 1,000,000,000,000,000,000,000 |
| exa | E | 10¹⁸ | 1E = 1,000,000,000,000,000,000 |
| peta | P | 10¹⁵ | 1P = 1,000,000,000,000,000 |
| tera | T | 10¹² | 1T = 1,000,000,000,000 |
| giga | G | 10⁹ | 1G = 1,000,000,000 |
| mega | M | 10⁶ | 1M = 1,000,000 |
| kilo | k | 10³ | 1k = 1,000 |
| — | — | 10⁰ | 1 = 1 |
| milli | m | 10⁻³ | 1m = 0.001 |
| micro | µ/u | 10⁻⁶ | 1µ = 0.000001 |
| nano | n | 10⁻⁹ | 1n = 0.000000001 |
| pico | p | 10⁻¹² | 1p = 0.000000000001 |
| femto | f | 10⁻¹⁵ | 1f = 0.000000000000001 |
| atto | a | 10⁻¹⁸ | 1a = 0.000000000000000001 |
| zepto | z | 10⁻²¹ | 1z = 0.000000000000000000001 |
| yocto | y | 10⁻²⁴ | 1y = 0.000000000000000000000001 |
| ronto | r | 10⁻²⁷ | 1r = 0.000000000000000000000000001 |
| quecto | q | 10⁻³⁰ | 1q = 0.000000000000000000000000000001 |
The simplest way to get started is using the convenience extensions:
import SwiftEngineeringNumberFormatter
// Double conversions
let value = Double(engineeringNotation: "2.2k") // Optional(2200.0)
let formatted = (1500.0).engineering // "1.5k"
// Decimal conversions (high precision)
let decimal = Decimal(engineeringNotation: "333n") // Optional(0.000000333)
let precision = decimal!.engineering // "333n"For more control, create a formatter instance:
let formatter = EngineeringNumberFormatter()
// Double formatting
let result1 = formatter.string(1_000_000.0) // "1M"
let parsed1 = formatter.double("2.5G") // Optional(2500000000.0)
// Decimal formatting (recommended for precision)
let result2 = formatter.string(decimal: Decimal(-1_000_000)) // "-1M"
let parsed2 = formatter.decimal("10p") // Optional(0.00000000001)Customize the formatter to match your requirements:
let formatter = EngineeringNumberFormatter(
minimumFractionDigits: 1, // Always show at least 1 decimal place
maximumFractionDigits: 3, // Limit to 3 decimal places
locale: Locale(identifier: "de_DE"), // German locale (comma separator)
useGreekMu: false, // Use 'u' instead of 'µ' for micro
addSpace: true // Add space between number and prefix
)
let result = formatter.string(2.222222e-6) // "2,222 u" (German formatting)When working with high-precision calculations, use Decimal to avoid floating-point arithmetic issues:
let formatter = EngineeringNumberFormatter()
// Double precision limitations
let doubleSum = formatter.double("0.2")! + formatter.double("100m")!
// doubleSum != 0.3 (floating point precision issues)
// Decimal precision advantage
let decimalSum = formatter.decimal("0.2")! + formatter.decimal("100m")!
// decimalSum == 0.3 (exact decimal arithmetic)
// High precision example
let highPrecision = formatter.decimal("1M")! + formatter.decimal("1f")!
// Exactly: 1000000.000000000000001The library gracefully handles invalid inputs:
let formatter = EngineeringNumberFormatter()
// These return nil for invalid inputs
formatter.double("") // nil
formatter.double("invalid") // nil
formatter.double("1.2.3k") // nil
formatter.decimal("µ") // nilAdd to your Package.swift:
dependencies: [
.package(url: "https://github.com/RuiCarneiro/SwiftEngineeringNumberFormatter", from: "3.0.0")
]Add to your target dependencies:
.target(
name: "YourTarget",
dependencies: ["SwiftEngineeringNumberFormatter"]
)- File → Add Package Dependencies
- Enter:
https://github.com/RuiCarneiro/SwiftEngineeringNumberFormatter - Select version and add to your target
- Swift 6.0+
- iOS 13.0+ / macOS 10.15+ / watchOS 6.0+ / tvOS 13.0+
- Linux (Swift Package Manager)
EngineeringNumberFormatter is marked as Sendable and is safe to use across multiple threads concurrently.
The library is optimized for performance with:
- Efficient string parsing algorithms
- Minimal memory allocations
- Built-in caching for number formatters
- Comprehensive test suite including performance benchmarks
The project uses Swift Testing framework (Swift 6.0+):
swift test # Run all tests
swift build # Build the packageGenerate documentation using Swift-DocC:
swift package generate-documentationContributions are welcome! Please feel free to submit a Pull Request.
Licensed under the Apache License, Version 2.0. See LICENSE for details.
© 2024 Rui Nelson