- Home /
Why is there no Mathf.Truncate?
I found it odd that there is no Mathf.Truncate function. I am working with floats in formulas and need to Floor positive floats while Ceiling negative floats. Essentially this is rounding a float towards zero. Also, you can do the opposite by using MidpointRounding.AwayFromZero but this seems to be missing in Unity's C# unless I'm doing something wrong.
Obviously, I can just use System.Math.Truncate but I have to convert my float equation into a double then cast truncate return to an int. This also makes me wish there was a TruncateToInt method as well.
Is there any reason for this?
Reference: System.Math.Truncate
Well that's strange, thanks VildNinja! I didn't realize just casting it straight to int does exactly what $$anonymous$$ath.Truncate does.
You should convert this comment to answer, because that is probably the reason $$anonymous$$athf doesn't have a truncate since it's easier to just to cast to int.
I would suggest looking into the $$anonymous$$athf functions in Unity. They likely have a lot of what you want, such a $$anonymous$$athf.Ceil and $$anonymous$$athf.Floor.
http://docs.unity3d.com/Documentation/ScriptReference/$$anonymous$$athf.html
http://docs.unity3d.com/Documentation/ScriptReference/$$anonymous$$athf.Ceil.html http://docs.unity3d.com/Documentation/ScriptReference/$$anonymous$$athf.Floor.html
I have looked throughout $$anonymous$$ath functions in Unity. I even stated the ceiling and flooring comments in my question. Ceil and Floor don't do what Truncate does and $$anonymous$$athf doesn't have anything close to Truncate.
$$anonymous$$athf.Ceil(3.7) = 4
$$anonymous$$athf.Ceil(-3.7) = -3$$anonymous$$athf.Floor(3.7) = 3
$$anonymous$$athf.Floor(-3.7) = -4$$anonymous$$ath.Truncate(3.7) = 3
$$anonymous$$ath.Truncate(-3.7) = -3
@VildNinja posted a comment stating that casting the float into an int will actually do what Truncate does.
Last I heard, the $$anonymous$$athf functions were just wrappers for System.$$anonymous$$ath anyway. If you write your own Truncate function which calls System.$$anonymous$$ath.Truncate and does the appropriate casting, then it will be exactly the same as if it was in $$anonymous$$athf.
Answer by VildNinja · Jan 27, 2014 at 02:18 AM
Per request: An answer!
In c# casting to int does that. Note that this is not common practice in all languages. In Java (not JavaScript) for instance the procedure is to always floor. In c++ it varies depending on OS/processor afaik both Intel and AMD Truncates which is probably also why MS decided to do the same for c#.
Answer by PaulUsul · Sep 25, 2019 at 07:27 PM
For anyone more curious here's some more info:
value truncate cast floor ceil
0 : 2.1 2 2 2 3
1 : 1.9 1 1 1 2
2 : 0.1 0 0 0 1
3 : 0 0 0 0 0
4 : -0.1 0 0 -1 0
5 : -1.9 -1 -1 -2 -1
6 : -2.1 -2 -2 -3 -2
run from this test
[Test]
public void TestTruncate()
{
float[] numbers = {2.1f, 1.9f, 0.1f, 0.0f, -0.1f, -1.9f, -2.1f};
Debug.Log($" value\ttruncate\tcast\tfloor\tceil");
for (int i = 0; i < numbers.Length; i++)
{
float value = numbers[i];
double truncate = Math.Truncate(value);
int cast = (int)(value);
int floor = Mathf.FloorToInt(value);
int ceil = Mathf.CeilToInt(value);
Debug.Log($"{i} : {value}\t{truncate}\t{cast}\t{floor}\t{ceil}");
}
}
It's nice to have such a comparison. Though I just had another look at the System.$$anonymous$$ath class and it looks like the only actual native method is the Floor method which is defined external. All the others (Ceiling and Truncate) are just using the floor function. Here are the implementations of Ceiling and Truncate directly taken from $$anonymous$$ono's System.$$anonymous$$ath class:
public static double Ceiling(double a)
{
double num = $$anonymous$$ath.Floor(a);
if (num != a)
num += 1.0;
return num;
}
public static double Truncate(double d)
{
if (d > 0.0)
return $$anonymous$$ath.Floor(d);
if (d < 0.0)
return $$anonymous$$ath.Ceiling(d);
return d;
}
So in terms of performance the "int cast" is probably the fastest one.
Note that the implementation of the actual .NET framework looks different. There, Floor and Ceiling are both directly implemented in native code. Truncate actually calls another internal native method (SplitFractionDouble).
Like Eric mentioned already in the comment above, Unity's $$anonymous$$athf class contains mostly wrapper methods which just call the System.$$anonymous$$ath counter part and cast the result to float. So using $$anonymous$$athf is not really "optimised" in any way. It's just there for convenience since Unity uses floats almost everywhere so you don't have to care about the casting.
Very interesting! This made me think of if the new $$anonymous$$athematics library would do it differently, but it just calls System.$$anonymous$$ath with casts. https://github.com/Unity-Technologies/Unity.$$anonymous$$athematics/blob/master/src/Unity.$$anonymous$$athematics/math.cs