A high-precision, deterministic fixed-point math library for .NET.
Ideal for simulations, games, and physics engines requiring reliable arithmetic without floating-point inaccuracies.
- Deterministic Calculations: Ensures consistent results across different platforms.
- High Precision Arithmetic: Uses fixed-point math to eliminate floating-point inaccuracies.
- Comprehensive Vector Support: Includes 2D and 3D vector operations (
Vector2d,Vector3d). - Quaternion Rotations: Leverage
FixedQuaternionfor smooth rotations without gimbal lock. - Matrix Operations: Supports transformations with
Fixed4x4andFixed3x3matrices. - Bounding Shapes: Includes
IBoundstructsBoundingBox,BoundingSphere, andBoundingAreafor lightweight spatial calculations. - Advanced Math Functions: Includes trigonometry and common math utilities.
- Framework Agnostic: Works with .NET, Unity, and other game engines.
- Flexible Serialization Options: The default build includes out-of-the-box
MemoryPacksupport across serializable structs, and aNoMemoryPackvariant is available for projects that need to avoid the MemoryPack dependency.
Clone the repository and add it to your project:
-
Choose the package that fits your runtime:
- Use
FixedMathSharpif you want the standard package with built-inMemoryPacksupport. - Use
FixedMathSharp.NoMemoryPackif you want the same math library without theMemoryPackdependency, such as when integrating with toolchains that do better without MemoryPack-generated code.
- Use
-
Install via NuGet:
-
Standard package:
dotnet add package FixedMathSharp
-
No-MemoryPack package:
dotnet add package FixedMathSharp.NoMemoryPack
-
If you're using
FluentAssertionsin your test project, the companion assertions package is available here: FixedMathSharp.FluentAssertions
-
-
Or Download/Clone:
-
Clone the repository or download the source code.
git clone https://github.com/mrdav30/FixedMathSharp.git
-
-
Add to Project:
- Include the FixedMathSharp project or its DLLs in your build process.
FixedMathSharp is published in two build variants so you can choose between convenience and maximum compatibility:
FixedMathSharpIncludesMemoryPackand its generated serialization support. This is the best default choice for most .NET applications.FixedMathSharp.NoMemoryPackExcludes theMemoryPackpackage and uses internal shim attributes so the same source can compile without the dependency. Choose this when you do not need built-in MemoryPack serialization, when you prefer to use a different serializer, or when your target environment is sensitive to MemoryPack-generated code paths.
Both variants expose the same core fixed-point math API. The main difference is whether MemoryPack is part of the package and serialization surface.
If you build from source, the repository also provides matching release configurations:
Releasebuilds the standardFixedMathSharppackage and archives.ReleaseNoMemoryPackbuilds theFixedMathSharp.NoMemoryPackpackage and archives.
If you use Unity Burst AOT, prefer the NoMemoryPack build. MemoryPack's Unity support is centered on IL2CPP via its .NET Source Generator path, so the no-MemoryPack variant is the safer choice for Burst AOT scenarios.
FixedMathSharp is now maintained as a separate Unity package. For Unity-specific implementations, refer to:
🔗 FixedMathSharp-Unity Repository.
If you are evaluating the .NET package directly for Unity-adjacent tooling, the NoMemoryPack variant is the safer starting point when you want to avoid the MemoryPack dependency entirely. In particular, if you use Burst AOT, prefer FixedMathSharp.NoMemoryPack.
Fixed64 a = new Fixed64(1.5);
Fixed64 b = new Fixed64(2.5);
Fixed64 result = a + b;
Console.WriteLine(result); // Output: 4.0Vector3d v1 = new Vector3d(1, 2, 3);
Vector3d v2 = new Vector3d(4, 5, 6);
Fixed64 dotProduct = Vector3d.Dot(v1, v2);
Console.WriteLine(dotProduct); // Output: 32FixedQuaternion rotation = FixedQuaternion.FromAxisAngle(Vector3d.Up, FixedMath.PiOver2); // 90 degrees around Y-axis
Vector3d point = new Vector3d(1, 0, 0);
Vector3d rotatedPoint = rotation.Rotate(point);
Console.WriteLine(rotatedPoint); // Output: (0, 0, -1)Fixed4x4 matrix = Fixed4x4.Identity;
Vector3d position = new Vector3d(1, 2, 3);
matrix.SetTransform(position, Vector3d.One, FixedQuaternion.Identity);
Console.WriteLine(matrix);BoundingBox box = new BoundingBox(new Vector3d(0, 0, 0), new Vector3d(5, 5, 5));
BoundingSphere sphere = new BoundingSphere(new Vector3d(3, 3, 3), new Fixed64(1));
bool intersects = box.Intersects(sphere);
Console.WriteLine(intersects); // Output: TrueFixed64 angle = FixedMath.PiOver4; // 45 degrees
Fixed64 sinValue = FixedTrigonometry.Sin(angle);
Console.WriteLine(sinValue); // Output: ~0.707Use DeterministicRandom when you need reproducible random values across runs, worlds, or features.
Streams are derived from a seed and remain deterministic regardless of threading or platform.
// Simple constructor-based stream:
var rng = new DeterministicRandom(42UL);
// Deterministic integer:
int value = rng.Next(1, 10); // [1,10)
// Deterministic Fixed64 in [0,1):
Fixed64 ratio = rng.NextFixed6401();
// One stream per “feature” that’s stable for the same worldSeed + key:
var rngOre = DeterministicRandom.FromWorldFeature(worldSeed: 123456789UL, featureKey: 0xORE);
var rngRivers = DeterministicRandom.FromWorldFeature(123456789UL, 0xRIV, index: 0);
// Deterministic Fixed64 draws:
Fixed64 h = rngOre.NextFixed64(Fixed64.One); // [0, 1)
Fixed64 size = rngOre.NextFixed64(Fixed64.Zero, 5 * Fixed64.One); // [0, 5)
Fixed64 posX = rngRivers.NextFixed64(-Fixed64.One, Fixed64.One); // [-1, 1)
// Deterministic integers:
int loot = rngOre.Next(1, 5); // [1,5)Fixed64Struct: Represents fixed-point numbers for precise arithmetic.Vector2dandVector3dStructs: Handle 2D and 3D vector operations.FixedQuaternionStruct: Provides rotation handling without gimbal lock, enabling smooth rotations and quaternion-based transformations.IBoundInterface: Standard interface for bounding shapesBoundingBox,BoundingArea, andBoundingSphere, each offering intersection, containment, and projection logic.FixedMathStatic Class: Provides common math and trigonometric functions using fixed-point math.Fixed4x4andFixed3x3: Support matrix operations for transformations.DeterministicRandomStruct: Seedable, allocation-free RNG for repeatable procedural generation.
Fixed64 is the core data type representing fixed-point numbers. It provides various mathematical operations, including addition, subtraction, multiplication, division, and more.
The struct guarantees deterministic behavior by using integer-based arithmetic with a configurable SHIFT_AMOUNT.
FixedMathSharp is optimized for high-performance deterministic calculations:
- Inline methods and bit-shifting optimizations ensure minimal overhead.
- Eliminates floating-point drift, making it ideal for lockstep simulations.
- Supports fuzzy equality comparisons for handling minor precision deviations.
Unit tests are used extensively to validate the correctness of mathematical operations. Special fuzzy comparisons are employed where small precision discrepancies might occur, mimicking floating-point behavior.
To run the tests:
dotnet test --configuration debug- .NET Standard 2.1
- .NET 8
- Unity 2020+ (via FixedMathSharp-Unity)
- Cross-Platform Support (Windows, Linux, macOS)
We welcome contributions! Please see our CONTRIBUTING guide for details on how to propose changes, report issues, and interact with the community.
- mrdav30 - Lead Developer
- Contributions are welcome! Feel free to submit pull requests or report issues.
For questions, discussions, or general support, join the official Discord community:
For bug reports or feature requests, please open an issue in this repository.
We welcome feedback, contributors, and community discussion across all projects.
This project is licensed under the MIT License.
See the following files for details:
- LICENSE – standard MIT license
- NOTICE – additional terms regarding project branding and redistribution
- COPYRIGHT – authorship information