Search Unity

Double to Float Rounding

Discussion in 'Scripting' started by ToshoDaimos, Aug 26, 2019.

  1. ToshoDaimos

    ToshoDaimos

    Joined:
    Jan 30, 2013
    Posts:
    679
    I use .NET Random class for generating samples in the range <0, 1.0). Note the upper bound is not included in this range. I then cast the result from double to float. Can this casting cause in rare cases rounding to 1.0? I'm not an expert in IEEE floating-point mechanics.
     
  2. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,605
    I tested this for you with the following code:
    Code (CSharp):
    1.         double d = 0.9999999999999d;
    2.         Debug.Log("Double value: " + d);
    3.         float f = (float)d;
    4.         Debug.Log("Float Value: " + f);
    5.  
    6.         double d2 = double.MinValue;
    7.         Debug.Log("Double value 2: " + d2);
    8.         float f2 = (float)d2;
    9.         Debug.Log("Float Value 2: " + f2);
    Getting the following results:
    > Double value: 0,9999999999999
    > Float Value: 1
    > Double value 2: -1,79769313486232E+308
    > Float Value 2: -infinity

    So apparantly yes, values can get rounded to 1 or infinity, even if they previously were not. Which makes sense, since we are losing precision. If necessary, you should check the value and reset it to <1 manually when the value is 1.
     
    ToshoDaimos likes this.
  3. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,775
    Do you have any practical use, for such high precision?
     
  4. ToshoDaimos

    ToshoDaimos

    Joined:
    Jan 30, 2013
    Posts:
    679
    I use it in random level generation. I got sometimes a crash because I then casted to int and indexed an array using Length instead of Length-1. :)
     
  5. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,775
    Maybe use int instead as random? Is more stable. Or uint, if you don't want negatives. Then you can use seeds. However int on its own is very long value mind. Do you realm need more than that? With float, passing seed is unreliable.

    What you can also do, is generate int,uint,long etc. and convert to float.

    Why do you need double precision, if you cast from float, to double float? Your results indeed maybe unpredictable. Do you do some additional math on new variable?
     
  6. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,532
    It's probably not that they need double precision. But rather that they're using System.Random which has 'Next' and 'NextDouble' which return int and double respectively. And they're going with NextDouble since it's a float rather than an int, and comes in the 0->0.99999 range that they expect rather than 0->int.Max (or the max passed in).

    @OP, your options are:

    use 'Next' with a max value of int that fits in float (16777216 ?), convert that int to float, and then divide that by the max value

    use 'NextDouble', cast to float, and use Clamp (or Math.Max/Min) to clamp it into 0->0.99999f.
     
    Last edited: Aug 26, 2019
    Antypodish likes this.