https://github.com/edadma/dynamic_complex.h
Single-header C library for arbitrary precision complex numbers with reference counting.
https://github.com/edadma/dynamic_complex.h
arbitrary-precision c c-library c11 complex-numbers reference-counting single-header
Last synced: 4 months ago
JSON representation
Single-header C library for arbitrary precision complex numbers with reference counting.
- Host: GitHub
- URL: https://github.com/edadma/dynamic_complex.h
- Owner: edadma
- License: other
- Created: 2025-09-16T01:51:06.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2025-09-16T04:33:45.000Z (5 months ago)
- Last Synced: 2025-09-16T06:22:16.593Z (5 months ago)
- Topics: arbitrary-precision, c, c-library, c11, complex-numbers, reference-counting, single-header
- Language: C
- Homepage: https://edadma.github.io/dynamic_complex.h/
- Size: 99.6 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# dynamic_complex.h
[](https://github.com/edadma/dynamic_complex.h/releases)
[](https://en.cppreference.com/w/c/11)
[](#license)
[](#platform-support)
[](#testing)
A single-header C library implementing arbitrary precision complex numbers with reference counting. Supports three distinct complex number types: integer (Gaussian), rational, and floating-point complexes.
## Features
- **Three Complex Types**: Gaussian integers, rational complex, and floating-point complex
- **Single Header**: Easy integration - just include `dynamic_complex.h`
- **Arbitrary Precision**: Built on dynamic_int.h and dynamic_fraction.h for exact arithmetic
- **Reference Counting**: Atomic memory management with configurable thread safety
- **Separate APIs**: Distinct function sets for each type (`dc_int_*`, `dc_frac_*`, `dc_double_*`)
- **Type Conversions**: Lossless upward conversions, rounding downward conversions
- **C99 Complex Integration**: Full transcendental function support for floating-point complex
- **Mathematical String Format**: Clean output like "3+4i", "2-3i", "i", "-i"
- **Fail-Fast Error Handling**: Assertions on invalid inputs for immediate bug detection
- **Comprehensive Testing**: 25 test cases with 100% function coverage
## Quick Start
First, ensure you have the required dependencies available in your include path:
- `dynamic_int.h`
- `dynamic_fraction.h`
Then include and use the library:
```c
// Include dependencies first (with their implementations if needed)
#define DI_IMPLEMENTATION // if using dynamic_int.h directly
#include "dynamic_int.h"
#define DF_IMPLEMENTATION // if using dynamic_fraction.h directly
#include "dynamic_fraction.h"
// Now include dynamic_complex.h
#define DC_IMPLEMENTATION
#include "dynamic_complex.h"
int main() {
// Integer complex (Gaussian integers)
dc_complex_int a = dc_int_from_ints(3, 4); // 3 + 4i
dc_complex_int b = dc_int_from_ints(1, -2); // 1 - 2i
dc_complex_int sum = dc_int_add(a, b); // 4 + 2i
// Rational complex (exact fractions)
dc_complex_frac c = dc_frac_from_ints(1, 2, 3, 4); // 1/2 + 3/4i
dc_complex_frac d = dc_frac_from_ints(1, 3, 1, 6); // 1/3 + 1/6i
dc_complex_frac frac_sum = dc_frac_add(c, d); // 5/6 + 11/12i
// Floating-point complex (with transcendental functions)
dc_complex_double e = dc_double_from_doubles(1.0, 0.0);
dc_complex_double f = dc_double_exp(dc_double_from_doubles(0.0, M_PI)); // e^(iπ) = -1
// Type conversions
dc_complex_frac exact = dc_int_to_frac(a); // Lossless: int → frac
dc_complex_double approx = dc_frac_to_double(c); // Convert: frac → double
// Division: integer division returns exact rational result
dc_complex_frac quotient = dc_int_div(a, b); // Exact rational division
// String output
char* str = dc_int_to_string(sum);
printf("Sum: %s\n", str); // "4+2i"
free(str);
// Cleanup (reference counting)
dc_int_release(&a);
dc_int_release(&b);
dc_int_release(&sum);
dc_frac_release(&c);
dc_frac_release(&d);
dc_frac_release(&frac_sum);
dc_double_release(&e);
dc_double_release(&f);
dc_frac_release(&exact);
dc_double_release(&approx);
dc_frac_release("ient);
return 0;
}
```
## Complex Types
### Integer Complex (`dc_complex_int`)
- **Purpose**: Gaussian integers (complex numbers with integer real and imaginary parts)
- **Backend**: Uses dynamic_int.h for arbitrary precision
- **Operations**: Exact arithmetic, division returns rational result
- **Example**: `3 + 4i`, `-7 + 2i`
### Rational Complex (`dc_complex_frac`)
- **Purpose**: Complex numbers with rational real and imaginary parts
- **Backend**: Uses dynamic_fraction.h for exact fraction arithmetic
- **Operations**: Exact rational arithmetic, automatic reduction to lowest terms
- **Example**: `1/2 + 3/4i`, `-2/3 + 5/7i`
### Floating-Point Complex (`dc_complex_double`)
- **Purpose**: IEEE 754 floating-point complex numbers
- **Backend**: Uses C99 complex.h for transcendental functions
- **Operations**: Standard complex arithmetic plus exp, log, sin, cos, etc.
- **Example**: `1.5 + 2.7i`, `3.14159 - 1.41421i`
## API Design
### Separate Function Families
Each complex type has its own complete API:
```c
// Integer complex functions
dc_complex_int dc_int_from_ints(int64_t real, int64_t imag);
dc_complex_int dc_int_add(dc_complex_int a, dc_complex_int b);
dc_complex_frac dc_int_div(dc_complex_int a, dc_complex_int b); // Returns fraction!
// Rational complex functions
dc_complex_frac dc_frac_from_ints(int64_t r_num, int64_t r_den, int64_t i_num, int64_t i_den);
dc_complex_frac dc_frac_mul(dc_complex_frac a, dc_complex_frac b);
bool dc_frac_is_gaussian_int(dc_complex_frac c); // Check if it's really an integer
// Floating-point complex functions
dc_complex_double dc_double_from_polar(double magnitude, double angle);
dc_complex_double dc_double_exp(dc_complex_double c); // All C99 complex.h functions
double dc_double_abs(dc_complex_double c); // Magnitude
```
### Type Conversions
```c
// Upward conversions (lossless)
dc_complex_frac dc_int_to_frac(dc_complex_int c);
dc_complex_double dc_int_to_double(dc_complex_int c);
dc_complex_double dc_frac_to_double(dc_complex_frac c);
// Downward conversions (with rounding)
dc_complex_int dc_frac_to_int(dc_complex_frac c); // Rounds to nearest Gaussian integer
dc_complex_int dc_double_to_int(dc_complex_double c); // Rounds both components
dc_complex_frac dc_double_to_frac(dc_complex_double c, int64_t max_denominator);
```
## Configuration
```c
// Memory management
#define DC_MALLOC custom_malloc
#define DC_FREE custom_free
#define DC_ASSERT custom_assert
// Thread safety (requires C11)
#define DC_ATOMIC_REFCOUNT 1
// Static linking
#define DC_STATIC
#define DC_IMPLEMENTATION
#include "dynamic_complex.h"
```
## Dependencies
### Required Dependencies
You must have these header files available in your include path:
- **dynamic_int.h**: Required for integer complex arithmetic
- Download from: https://github.com/edadma/dynamic_int.h
- **dynamic_fraction.h**: Required for rational complex arithmetic
- Download from: https://github.com/edadma/dynamic_fraction.h
- **C99 complex.h**: Used for floating-point transcendental functions (standard library)
### Development Dependencies (optional)
- **Unity**: Testing framework (included in devDeps/ for development)
### Dependency Setup
You have several options for managing dependencies:
1. **Manual Download**: Download the header files and place them in your include path
2. **Git Submodules**: Add dependencies as git submodules
3. **Package Manager**: Use a C package manager like CPM or Conan
4. **System Install**: Install headers system-wide
5. **CMake Include Directories**: Add dependency paths to your CMakeLists.txt
Example with git submodules:
```bash
git submodule add https://github.com/edadma/dynamic_int.h.git deps/dynamic_int
git submodule add https://github.com/edadma/dynamic_fraction.h.git deps/dynamic_fraction
```
Example CMakeLists.txt setup:
```cmake
include_directories(deps/dynamic_int.h)
include_directories(deps/dynamic_fraction.h)
```
## Building
```bash
# Build the test suite
mkdir build && cd build
cmake ..
make
# Run tests
./tests
# All 25 tests should pass with 100% function coverage
```
### Test Organization
The test suite is organized into logical groups:
1. **Integer Complex Tests** (6 test functions)
- Basic functionality, arithmetic, memory management, missing functions coverage
2. **Rational Complex Tests** (7 test functions)
- Creation, arithmetic, memory management, comparisons, string formatting
3. **Floating-Point Complex Tests** (8 test functions)
- Creation, arithmetic, transcendentals, special values, comprehensive coverage
4. **Type Conversion Tests** (2 test functions)
- All conversion paths between the three types
5. **Edge Cases and Formatting** (2 test functions)
- Mathematical identities, string formatting, boundary conditions
Each test function thoroughly exercises multiple related functions to ensure complete coverage and mathematical correctness.
## Integration with Interpreters
This library is designed for language interpreters with separate numeric types:
```c
// Interpreter can map types directly:
typedef enum {
TYPE_INT_COMPLEX, // -> dc_complex_int
TYPE_RATIONAL_COMPLEX, // -> dc_complex_frac
TYPE_FLOAT_COMPLEX // -> dc_complex_double
} complex_type_t;
// Type promotion handled by interpreter
dc_complex_frac promote_int_to_frac(dc_complex_int c) {
return dc_int_to_frac(c); // Exact conversion
}
```
## Mathematical Properties
- **Gaussian Integer Division**: `dc_int_div()` returns exact rational results
- **Automatic Reduction**: Rational complex numbers kept in lowest terms
- **Sign Normalization**: Denominators always positive, sign in numerator
- **IEEE 754 Compliance**: Floating-point complex follows C99 standard
- **String Format**: Mathematical notation ("3+4i", "2-3i", "i", "-i")
## Error Handling
The library uses a **fail-fast** approach:
- NULL pointer assertions (except in release functions)
- Memory allocation failure assertions
- Division by zero assertions
- All errors provide descriptive messages
## Performance Features
- **Cached Constants**: Singleton objects for 0, 1, i, -1, -i
- **Reference Counting**: Efficient memory sharing
- **Atomic Operations**: Optional thread-safe reference counting
- **C99 Integration**: Hardware-accelerated transcendental functions
## Testing
Comprehensive test suite with 25 test cases achieving **100% function coverage**:
### Integer Complex Tests (dc_int_*)
- Creation functions (`dc_int_from_ints`, `dc_int_from_di`, constants)
- Complete arithmetic operations (add, sub, mul, div, negate, conjugate)
- Memory management (retain, release, copy)
- Comparison predicates and string formatting
- Edge cases and mathematical identities
### Rational Complex Tests (dc_frac_*)
- Creation from integers and fractions (`dc_frac_from_ints`, `dc_frac_from_df`)
- Complete arithmetic suite (add, sub, mul, div, negate, conjugate, reciprocal)
- Gaussian integer detection predicate
- Memory management and equality testing
- String representation with fraction notation
### Floating-Point Complex Tests (dc_double_*)
- Creation from Cartesian and polar coordinates
- Basic and complete arithmetic operations
- **Full transcendental function suite**: exp, log, pow, sqrt, sin, cos, tan, sinh, cosh, tanh
- Special value detection (NaN, infinity)
- Memory management and string formatting
- Mathematical identity verification (e^(iπ/2) = i, sqrt(-1) = i)
### Type Conversion Tests
- Lossless upward conversions (int→frac→double)
- Lossy downward conversions with rounding
- Exact and approximate fraction conversion from doubles
- Conversion accuracy validation
### Comprehensive Coverage
- **All 65+ functions tested** across three complex types
- Memory management (reference counting, retain/release, copy)
- Mathematical correctness validation
- String formatting for all representations
- Edge cases, special values, and error conditions
- Cross-type operations and conversions
## Version History
### v0.1.0 (2025-09-16) - Initial Release
**Features:**
- Three distinct complex number types:
- Gaussian integers (`dc_complex_int`) - arbitrary precision integer complex
- Rational complex (`dc_complex_frac`) - exact fraction arithmetic
- Floating-point complex (`dc_complex_double`) - IEEE 754 with transcendentals
- Complete arithmetic operations for all types
- Full C99 complex.h transcendental function support
- Type conversions between all three types
- Reference counting memory management with optional atomic operations
- Mathematical string formatting ("3+4i", "1/2+3/4i")
- Fail-fast error handling with descriptive assertions
**API:**
- 65+ functions across three complete APIs (`dc_int_*`, `dc_frac_*`, `dc_double_*`)
- Separate function families for clean interpreter integration
- Lossless upward conversions, rounding downward conversions
- Gaussian integer division returns exact rational results
**Quality:**
- 100% function coverage with 25 comprehensive test cases
- Mathematical correctness validation
- Complete Doxygen documentation
- Cross-platform support (Linux, Windows, macOS, embedded)
- Single-header library design
**Dependencies:**
- Requires `dynamic_int.h` and `dynamic_fraction.h`
- Uses C99 `complex.h` for transcendental functions
- CMake build system with flexible dependency management
## License
Dual licensed under your choice of:
- [MIT License](LICENSE)
- [Unlicense (Public Domain)](LICENSE)
Choose the license that best fits your project's needs.
## Contributing
This library follows strict design principles:
- Fail-fast error handling
- Comprehensive testing required
- Mathematical correctness over convenience