Search Unity

Round to a decimal point ?

Discussion in 'Scripting' started by KenClemson, Dec 21, 2016.

  1. KenClemson

    KenClemson

    Joined:
    Oct 6, 2016
    Posts:
    24
    Hi I need to only have 1 decimal place in my number but I can seem to get this function to work.

    e.g I need 20.9 but when it cycles through the mathf.Movetowards function I get 18.9999999 etc etc.
    Anyway here is my code.
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.UI;
    4.  
    5. public class TestDecimal : MonoBehaviour
    6. {
    7.  
    8.     public float default_O2Value = 20.9f;
    9.     public float currentOxygenValue;
    10.     float O2Value;
    11.     float recoveryTime;
    12.  
    13.     public Text Oxygen_Value;
    14.  
    15.  
    16.  
    17.  
    18.     void Update ()
    19.     {
    20.  
    21.  
    22.  
    23.         currentOxygenValue = Mathf.MoveTowards(currentOxygenValue, O2Value, recoveryTime * Time.deltaTime);
    24.         Oxygen_Value.text = currentOxygenValue.ToString();   // trying to use System.Math.Round(val , 1) but cant get it to work
    25.         //Oxygen_Value.text = System.Math.Round(currentOxygenValue.ToString(), 1.0f);   //Cant make it work
    26.     }
    27. }
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,531
    1) Math.Round takes a double and int, not a string and float. So that second commented out line is a no go.

    2) always remember that floats will always be prone to small error. This is because it's stored in both binary and has a finite number of digits. The issue that arises is that values like .1 (or a multiple there of, like .9) are repeating values.

    0.1 dec ~ 0.0001100110011...
    0.9 dec ~ 0.11100110011...

    But since a float can only store a finite number of digits, as opposed to an infinite repeating series, the value ends up always being just shy of the expected result. Which is where the float error comes from (your .999999).

    3) Rounding 18.99999 to one place won't giver you 18.9, it'll give you 19. It'll end up rounding up. You'll want to floor to one decimal place if you expect 18.9

    here you can find my FloorTo method which gives flooring to a specific place:
    https://github.com/lordofduct/space.../blob/master/SpacepuppyBase/Utils/MathUtil.cs

    Code (csharp):
    1.  
    2.         /// <summary>
    3.         /// FloorTo some place comparative to a 'base', default is 10 for decimal place
    4.         ///
    5.         /// 'place' is represented by the power applied to 'base' to get that place
    6.         /// </summary>
    7.         /// <param name="value"></param>
    8.         /// <param name="place"></param>
    9.         /// <param name="base"></param>
    10.         /// <returns></returns>
    11.         /// <remarks></remarks>
    12.         public static float FloorTo(float value, int place, uint @base)
    13.         {
    14.             if (place == 0)
    15.             {
    16.                 //'if zero no reason going through the math hoops
    17.                 return (float)Math.Floor(value);
    18.             }
    19.             else
    20.             {
    21.                 float p = (float)Math.Pow(@base, place);
    22.                 return (float)Math.Floor(value * p) / p;
    23.             }
    24.         }
    25.  
    Of course float error is an issue.

    4) ToString allows format strings, try something like:

    Code (csharp):
    1.  
    2. Oxygen_Value.text= currentOxygenValue.ToString("#0.0");
    3.  
    Of course the actual value won't be that, but the displayed value will.

    This format string says:
    # - if there is a digit in this place or larger, show it, otherwise nothing.
    first 0 - always show a digit, if no digit, show 0
    . - show the decimal point
    second 0 - always show the first decimal place, if no decimal value there, show 0
     
    aeffoa and entropicjoey1 like this.
  3. KenClemson

    KenClemson

    Joined:
    Oct 6, 2016
    Posts:
    24
    Ok thanks Ill try it out
     
  4. KenClemson

    KenClemson

    Joined:
    Oct 6, 2016
    Posts:
    24
    awesome thanks lordofduct, that fixed it Oxygen_Value.text= currentOxygenValue.ToString("#0.0");

    Thanks so much for your help. Im a bit new in the forums, how do you mark this thread as solved ?
     
    entropicjoey1 likes this.
  5. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Marking a thread as solved isn't a part of the culture here. We just call a thread done once people stop commenting on it. Some people will put solved in the title, but it's not needed.
     
    TaleOf4Gamers likes this.
  6. KenClemson

    KenClemson

    Joined:
    Oct 6, 2016
    Posts:
    24
    Ok cool culture learnt. Thanks.