asik / fixedmath.net Goto Github PK
View Code? Open in Web Editor NEWFixed point math C# library
License: Other
Fixed point math C# library
License: Other
This library implements "Fix64", a 64 bit fixed point 31.32 numeric type and transcendent operations on it (square root, trig, etc). It is well covered by unit tests. However, it is still missing some operations; in particular, Tangent is not well tested yet. In the unit tests you'll find implementations for Int32-based (Q15.16) and Byte-based (Q3.4) numeric types. These were used for exploration of boundary conditions etc., but I'm keeping the code there only for reference. This project started as a port of libfixmath (http://code.google.com/p/libfixmath/). Note that the type requires explicit casts to convert to floating point and this is intentional, the difference between fixed point and floating point math is as important as the one between floating point and integral math.
I am exploring to use this library in a financial application where base 10 calculations must be correct within 10 decimal paces.
System.Decimal provides correct base 10 math within its precision range, I believe 28 decimal places.
This library is very exciting because many applications can benefit from a faster, yet correct numeric data type.
How does this library compare to System.Decimal in terms of correctness?
public static Fix64 Pow(Fix64 b, Fix64 exp)
if b is negative, Log2 will Throw exception.
bool isNeg = false;
if (b.m_rawValue < 0)
{
isNeg = true;
}
Fix64 log2 = isNeg ? Log2(-b) : Log2(b);
This isn't an issue with FixedMath.Net, but I'm running out of places to ask about this.
My game has been built to use deterministic lockstep for networked multiplayer. Relatively recently I finally got online games to last more than five minutes before desyncing. The game is now at a point where things are desyncing inconsistently, in a way that is difficult to reproduce reliably. Until now, I have been using checksums, dumping readable gameplay data to file, and other tedious methods of debugging. (Sometimes resulting in 3+mb text files)
My question is... are there tools or methods to more easily debug this sort of thing?
Someone suggested I create a bot to automatically do the same action over and over until a desync occurs. This would help rule out certain weapons/actions, but it still has issues and is tedious. I thought about maybe some kind of memory dump? I really have no idea how I would do that though, and even then it would pose its own problems...
This game has been quite a trek for me. Any insights much appreciated. :)
For my project, I would much prefer to have more integer places than decimal places. (I'm thinking maybe 5 or 8 decimal places)
If I change "const int FRACTIONAL_PLACES = 32;" to a lower value will everything still work correctly? Or do more changes need to be made or is it just plain unsupported?
Also, I'll probably be making a few extensions for this, like Vector2 or Vector3. They probably won't be that in depth, but would you be interested in something like this?
It's been hard to find any good libraries out there, and I'm not so great at the heavy math stuff, so thank you for your efforts! :)
Not realy an issue at all, couldnt see a way to contact you any other way though.
Just to say thanks for this library, we're using a slightly modified version in our project here https://bitbucket.org/ekolis/freee/
and
here https://bitbucket.org/se5a/newtmath
(the slightly modified version here https://bitbucket.org/se5a/fixmath.net/overview - mostly just some implicit conversions, and ability to compile for .net 4.0 feel free to use any of the changes)
Great work! Nice to have a profiling report comparing to float/double on different platforms, including desktops and mobiles, etc.
First off, thank you so much for this library. It's the only one that I've found that I've gotten working for my application.
The one thing that it's missing that I really need is to be able to calculate fractional powers, the same as Mathf.Pow() does. I've found at least one library that seems to do it in 32bit (https://github.com/jpernst/FixedPointy/blob/master/FixMath.cs) but I lack the mathematical/bit manipulation skill to add it to your library. I think the place where I get tripped up in the FixedPointy implementation is it uses long to get enough space when calculating Pow(), so I'm not sure what to do to add it to your library.
It throw out exception "Must between -FP.One and FP.One"
The demo is as follow:
FP x1 = FP.FromRaw(3492999344);
FP y1 = FP.FromRaw(2499139782);
FP x2 = FP.FromRaw(-3492914803);
FP y2 = FP.FromRaw(-2499256617);
Debug.Log("x1: " + x1 + " y1: " + y1 + " x2: " + x2 + " y2: " + y2);
// x1: 0.8132773 y1: 0.5818763 x2: -0.8132576 y2: -0.5819035
FP x1_normalized = x1 / FP.Sqrt(x1 * x1 + y1 * y1);
FP y1_normalized = y1 / FP.Sqrt(x1 * x1 + y1 * y1);
Debug.Log("normalized vector1 x: " + x1_normalized + " y: " + y1_normalized);
// normalized vector1 x: 0.8132773 y: 0.5818763
FP x2_normalized = x2 / FP.Sqrt(x2 * x2 + y2 * y2);
FP y2_normalized = y2 / FP.Sqrt(x2 * x2 + y2 * y2);
Debug.Log("normalized vector2 x: " + x2_normalized + " y: " + y2_normalized);
// normalized vector2 x: -0.8132578 y: -0.5819036
FP dot = x1_normalized * x2_normalized + y1_normalized * y2_normalized;
Debug.Log("Dot of vector1 and vector2: " + dot);
// Dot of vector1 and vector2: -1
FP.Acos(dot);
// ArgumentOutOfRangeException: x
// Parameter name: Must between -FP.One and FP.One
The code of Fix64:
/// <summary>
/// Returns the arccos of of the specified number, calculated using Atan and Sqrt
/// This function has at least 7 decimals of accuracy.
/// </summary>
public static FP Acos(FP x)
{
if (x < -One || x > One)
{
throw new ArgumentOutOfRangeException("Must between -FP.One and FP.One", "x");
}
if (x.RawValue == 0) return PiOver2;
var result = Atan(Sqrt(One - x * x) / x);
return x.RawValue < 0 ? result + Pi : result;
}
Good Repo!
I have met a problem to the sqrt
for Q48.15 format fixed point. I try to modify your sqrt
code, but can not get the correct answer. Is your sqrt
only available on Q31.32 format? Code below is my version, I use NUM_BITS /4 - 1
to represent number 15
. I would also glad if you can list the detail comments of the fixed point sqrt
implementation.
public static Fix64 Sqrt(Fix64 x) {
var xl = x.m_rawValue;
if (xl < 0) {
// We cannot represent infinities like Single and Double, and Sqrt is
// mathematically undefined for x < 0. So we just throw an exception.
throw new ArgumentException("Negative value passed to Sqrt", "x");
}
var num = (ulong)xl;
var result = 0UL;
// second-to-top bit
var bit = 1UL << (NUM_BITS - 2);
while (bit > num) {
bit >>= 2;
}
// The main part is executed twice, in order to avoid
// using 128 bit values in computations.
for (var i = 0; i < 2; ++i) {
// First we get the top 48 bits of the answer.
while (bit != 0) {
if (num >= result + bit) {
num -= result + bit;
result = (result >> 1) + bit;
}
else {
result = result >> 1;
}
bit >>= 2;
}
if (i == 0) {
// Then process it again to get the lowest 16 bits.
if (num > (1UL << (NUM_BITS / 4 - 1)) - 1) {
// The remainder 'num' is too large to be shifted left
// by 32, so we have to add 1 to result manually and
// adjust 'num' accordingly.
// num = a - (result + 0.5)^2
// = num + result^2 - (result + 0.5)^2
// = num - result - 0.5
num -= result;
num = (num << (NUM_BITS / 4 - 1)) - 0x4000UL;
result = (result << (NUM_BITS / 4 - 1)) + 0x4000UL;
}
else {
num <<= (NUM_BITS / 4 - 1);
result <<= (NUM_BITS / 4 - 1);
}
bit = 1UL << (NUM_BITS / 4 - 2 - 1);
}
}
// Finally, if next bit would have been 1, round the result upwards.
if (num > result) {
++result;
}
return new Fix64((long)result);
}
Hi,
conversions from/to double
& float
are using floating point multiplication/division which is not deterministic across platforms. Is there any chance to make them deterministic?
Thanks for you work!
Is this library deterministic across processor architectures (aside from perhaps the floating point conversions)?
FixedMath.Net seems to be almost completely possible to convert into an FPGA-based hardware implementation with our Hastlayer project. Hastlayer can automatically convert a subset of .NET into hardware implementations, providing significantly better performance in massively parallelizable compute-bound algorithms with lower power consumption.
And fixed point is very efficient with FPGAs.
Would be quite cool. What do you think?
Hello, I currently write my own version of a 32bit integer fixed-point math.
I only have square root left to do, and all these custom sqrt algorithms seem to be still slower than just performing the regular Math.Sqrt and cast it to int. The Dijkstras Square Root you seem to use is for example ~10 times slower than using+casting Math.Sqrt.
So I wonder if I just should do that. Rounding errors, which you try to avoid by using Fix math, are no matter here as the raw number has no point anyway, after which the machine-dependent rounding errors occurs.
Would like to hear your opinion on this. This is not really an "issue" but I am not sure how else to ask on Github.
I am working on imaging stuff, like triangle rasterization, etc, where I need fast, fixed point arithmetics within small range sizes (typically between -10000 to 10000) for fast line/triangle gradient calculation on images. Fixed64 is probably too big, but Fixed32 would be more than enough.
Performance wise, I don't know if on modern CPUs a Fixed32 would be faster than Fixed64... but if it is, it could be worth having a Fixed32 type.
Exploring the current code of Fixed64, I've found some details that I think could be improved:
INTEGER_MASK=0xffffffff00000000;
and FRACTIONAL_MASK = 0x00000000ffffffff;
that would definitely help porting Fixed64 to other sizes.long
and ulong
, you could declare aliases like this: using RAWSIGNED = long;
and using RAWUNSIGNED = ulong;
and use the aliases along the code, again, for the sake of porting to other sizes.public readonly struct { }
which enforces the struct to be inmutable; apparently this gives a lot of performance benefits, more hereFix64 Min(Fix64 a, Fix64 b);
and Fix64 Max(Fix64 a, Fix64 b);
functionsSorry,excuse me!
When I use reflection,it will show the error! For I test, the file "Fix64SinLut" and "Fix64TanLut" is so large!
I use it for moba game by Unity!
how can I solve this problem
I'm trying to use the Fix64 in a Unity game project. Unity supports only .NET 2.0/3.5 era functionality. So I changed the project to .NET 3.5. After commented out unused "using System.Numerics" and "using System.Threading.Tasks" it was only "MethodImplOptions.AggressiveInlining" which was not available for .NET 3.5. After running the tests only the Sin() of Fix8 failed. So Fix64 seems to be working on .NET 3.5.
Do you think there might be any problems even the tests run through? Will the missing "MethodImplOptions.AggressiveInlining" be a big performance issue?
Thanks for your work! I keep you updated on the progress if your interested :-)
Cheers,
Markus
Probably a dumb question but -
Would converting from a float to a Fix64 be consistent across CPU architectures?
float z = 0.123456789123f;
Fix64 x = (Fix64)z; // Always the same
Opp! using fixed point
can't search any C# stuffs in Github, why don't you add the keywords in your description let people can find you.
Thanks to your code, I am struggling against it right now.
Conversion from float and double emit conv.i8 instructions which are unspecified in case of overflow; this means the type has unspecified behavior in this case.
The best approach would be to throw OverflowException in these cases, by emitting conv.ovf.i8 instead. The checked keyword in C# allows this.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.