# Huge Math Error In C#

Hey everyone, I am currently working on a networking system for a shooter. The Stat of the player is sent through a float value and the ID of the player is also stored in the same float value. Basically the current stat is stored as an Int and the ID of the player is stored in decimal places below 1.

Example: Players stat is 10. Players ID is 4. The number which is sent will be 10.04.

Upon receiving, I separate the 2 using simple math.

Int RecievedStat = (int)RecievedFloat;

Int PlayerID = (int)((RecievedFloat - RecievedStat) * 100);

You would think Unity could carry out some simple subtraction but I have been getting so many math errors it’s unusable.

Unfortunately, likely the only way I can fix this is by first multiply the 2 by 100 and then dealing with strictly Int’s…

Here is a screenshot of these horrifying math errors in action.

That’s just typical floating point imprecision; nothing related to Unity or C#. Don’t use floats if you don’t want that to happen.

–Eric

That’s just floating point precision.
You would be better off sending an int e.g. 1004, then just dividing by 100 and rounding to get 10, then doing a modulus division to get the 4.

Or better still sending two bytes as a short then separating the bytes with shift operations (which are very fast).

I have a feeling that when you do (RecievedStat - RecievedFloat), since the first one is a int, it does an implicit conversion to int.

So, try this;

``````Int PlayerID = (int)(((float)RecievedStat - RecievedFloat) * 100.0f);
``````

Thanks for the answers guys. Yeah I got it working by simply reversing the formula (Going Int first). I just find it strange that after all the years of working with things like this I never encountered this…

Basically ANY time you subtract something and the answer equals 1, it always seems to equal 0.999999999. How have I never stumbled across this?

It’s one of those things that you THINK would happen all the time, but somehow, only happens occasionally. How often do you a) do math on floats and b) expect a value that is perfectly precise? I mean, it just doesn’t come up very much, especially if you use ints for situations like this one (and you should; even without float imprecision issues, it’s still less data to send an int and less processing time to split it apart into its constituent pieces).

tl;dr: Usually when you need precision of this sort, the correct choice is ‘int’ even if precision wasn’t a problem, therefore it doesn’t come up often.

The reason for using floats might be a little more clever than you might think. Obviously the players position and orientation need to be sent yes? We know floats/vector3’s need to be used for world position as well as orientation. However when it comes to orientation, we don’t need the Z in XYZ. So I use Z to hold both the stat and ID of the player. So everything about the player that the client’s ever need to know is sent in two Vector3’s.

Edit: I would use Byte arrays, but there really is no point at all. I need high precision floats for the position and rotation, and that’s tecnically all I’m sending.

I would not use the Z position like that, either, even if all of the previous things weren’t the case. I think Unity does some compression and optimization of the position/rotation before it sends it across the network.

Its zrotation. And its working perfectly. The problem wasn’t occurring through the sends and receives, it was just the float precision’s. Plus regardless of what Unity is doing it doesn’t need to be that accurate as long as they are correctly rounded.