Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

UnityEngine.Mathf should use System.MathF

Discussion in 'Experimental Scripting Previews' started by runner78, Oct 12, 2021.

  1. runner78

    runner78

    Joined:
    Mar 14, 2015
    Posts:
    792
    I have seen UnityEngine.Mathf often uses the double based System.Math. But since .NET Standard 2.1 there are System.MathF.

    Unity from 2021.2 could switch to the new library and thus should improve performance in some places.
     
  2. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,936
    We have not done it so far because the UnityEngine assembly code does not have access to the .NET Standard 2.1 APIs. But we're working on changing that internally now. Once that is complete, then we can look at doing this. There are a few caveats related to the VM implementations though.

    For IL2CPP, the UnityEngine.Mathf APIs are already re-mapped as intrinsics to C standard library methods that do floating point math, so I think we're already getting the best performance.

    For Mono, the Mono version Unity used prior to Unity 2021.2 always did floating point math using 64-bit doubles, so this would not provide any benefit. The newer Mono has an option to use 32-bit floats, but that changes the behavior of some floating point code, so if we enable that, it will likely be an option.

    But at the API level, I think this suggestion makes a lot of sense. I'll raise it with the team. Thanks!
     
    andyz, stonstad, SirIntruder and 3 others like this.
  3. CaseyHofland

    CaseyHofland

    Joined:
    Mar 18, 2016
    Posts:
    613
    If you're doing work on the Mathf class anyway, I think I found an improvement to
    Mathf.Repeat
    , although I haven't done any tests.

    Code (CSharp):
    1. // Current implementation
    2. public static float Repeat(float t, float length)
    3. {
    4.     return Clamp(t - Floor(t / length) * length, 0f, length);
    5. }
    6.  
    7. // My implementation
    8. public static float Repeat(float t, float length)
    9. {
    10.     return (length + t % length) % length;
    11. }
    This has 2 division operators but no if checks (and is really elegant). It also only needs 2 interfaces from the System.Numerics namespace if you ever upgrade the API to include it (IAdditionOperators and IModulusOperators).

    Code (CSharp):
    1. t = 8, length = 6
    2. (6 + 8 % 6) % 6
    3. = (6 + 2) % 6
    4. = 8 % 6
    5. = 2
    6.  
    7. t = -512, length = 17
    8. (17 + -512 % 17) % 17
    9. = (17 + -2) % 17
    10. = 15 % 17
    11. = 15
     
    JoshPeterson likes this.
  4. M_R

    M_R

    Joined:
    Apr 15, 2015
    Posts:
    559
    this can further be simplified to
    (length + t) % length
    because Zn is a ring.
    (unless there is some corner case with negative length)
     
  5. CaseyHofland

    CaseyHofland

    Joined:
    Mar 18, 2016
    Posts:
    613
    Oh right, I should look into negative length…

    The method you suggested wouldn’t work: the extra modulo is needed to account for t negative
    Code (CSharp):
    1. t = -512, length = 17
    2. (17 + -512) % 17
    3. = -495 % 17
    4. = -2 // should be 15
     
    Last edited: Aug 21, 2023
  6. CaseyHofland

    CaseyHofland

    Joined:
    Mar 18, 2016
    Posts:
    613
    Code (CSharp):
    1. t = 512, length = -17
    2. (-17 + 512 % -17) % -17
    3. = (-17 + 2) % -17
    4. = -15 % -17
    5. = -15
    Code (CSharp):
    1. t = -512, length = -17
    2. (-17 + -512 % -17) % -17
    3. = (-17 + -2) % -17
    4. = -19 % -17
    5. = -2
    It actually works!

    Unfortunately, a thread pointed out that this would not work for e.g. int.MaxValue because you would get an overflow exception.

    There is a smarter answer hidden in this thread somewhere but I go sleep sleep now :3

    https://stackoverflow.com/a/51018529
     
    Last edited: Aug 21, 2023