Getting A Random Between Two Doubles
Apparently in regular Javascript, there is a Math.Random() function that returns a double value between 0.0 and 1.0 so that I can get a random value between incredibly large or small values.
Unity doesn't know what it is, though. This is the code I'm using.
class ObjectClass {
var min_amount : System.Double = 1 / System.Double.MaxValue;
var max_amount : System.Double = System.Double.MaxValue;
var range : System.Double;
var amount : System.Double;
}
var ObjectProperties : ObjectClass;
function Start () {
ObjectProperties.range = ObjectProperties.max_amount - ObjectProperties.min_amount;
ObjectProperties.amount = (Math.Random() * ObjectProperties.range) + ObjectProperties.max_amount;
}
Now according to this site Math.Random() should be valid, but it doesn't look like Unity uses it. Is there any way to get a random between two System.Double values in Unity?
Answer by balikaa16 · Feb 01, 2016 at 06:59 PM
Try using Random.Range. It uses floats though.
Random.Range is a problem since its $$anonymous$$imum and maximum numbers are way too small for what I want to use the numbers for. System.Double can go up to ~1.8E308 and down to ~5.56E-309, floats can only go up to about... 20 or so digits both ways, I think.
Floats have a range of 1.18E-38 to 1.7E+38. However keep in $$anonymous$$d that that range just defines the maximum and $$anonymous$$imum values. Even doubles have about 10 times the max range, the precision is only about doubled (hence the names single precision and double precision).
Floats have 24 significant digits(bits) which gives about 6 - 9 decimal significant digits.
Doubles have 53 significant digits(bits) which gives about 15–17 decimal significant digits.
It's not clear for what you need those values, but in most cases the precision limitation is way more important than the max range. So even though a double value can be 308 digits long, only the first 17 digits can actually be used. so if you try to change the "18th" digits in a 308 digit number that's not possible
// double
1.2345678911234567*10^308 ==
12345678911234567000000000000000000000000000000000000....
| <-- 15-17 --> | can't be changed --> ....
// float
1.23456789*10^38 ==
12345678900000000000000000000000000000
|<-6-9->| can't be changed --> ....
The section of the significant digits can "float" around but you always have only about 16 digits for double and about 8 digits for single (float) values.
Depending on what you want to express with your numbers, floating point values may not be the right thing in general. If you need "infinite" / adaptive precision you have to use something like a BigInt / BigFloat library
That was very informative on the background of coding information. Unfortunately, since it looks like Unity doesn't have a standard method for getting a random between 2 doubles (strictly) it looks like I have to go with floats. It's a bit of a shame, since I wanted to use as many numbers as possible, but it looks like I have no choice.
Answer by Eric5h5 · Feb 01, 2016 at 08:00 PM
Unity doesn't use Javascript (rather Unityscript, which is a custom language), and the site you linked to is about Java, which is an entirely 100% different language, and Unity does not use that, either. Unity scripting is built .NET/Mono, so use System.Math.Random. .NET uses doubles for math stuff. (Fun fact: Mathf functions in Unity typically just call System.Math functions, while converting doubles to singles.) BTW, you can just write "var min_amount : double".
The site still helps, it's actually been a 1-to-1 match every other time with syntax, this is the first time that the syntax has been wrong.
So I can just do this?
var $$anonymous$$_amount : double = 1 / double.$$anonymous$$axValue;
var max_amount : double = double.$$anonymous$$axValue;
function Start () {
System.$$anonymous$$ath.Random($$anonymous$$_amount, max_amount);
}
Answer by Bunny83 · Feb 01, 2016 at 11:46 PM
The whole Unity engine is designed for single floating point values. For most cases in a 3d engine, single precision is enough. Also the GPU hardware is optimised for 32-bit single precision floating point values.
So while Unity could have provided an additional random method which returns double values it just wouldn't fit the rest of the API.
Anyways you still can use the random number generator that comes with the .NET / Mono framework. Since UnityScript is also a .NET / Mono language you have access to the same classes as C# has.
The System.Random
class requires you to create an instance of the class in order to use it. You can create a static wrapper class like this:
// DRandom.cs
using System;
public static class DRandom
{
private static Random m_Rnd ;
private static int m_LastSeed;
static DRandom()
{
var v = DateTime.Now.Ticks;
m_LastSeed = (int)(v ^ (v >> 7) ^ (v >> 17));
m_Rnd = new Random(m_LastSeed);
}
public static int seed
{
get { return m_LastSeed; }
set { m_LastSeed = value; m_Rnd = new Random(m_LastSeed); }
}
public static double value
{
get { return m_Rnd.NextDouble(); }
}
public static double Range(double aMin, double aMax)
{
return aMin + m_Rnd.NextDouble() * (aMax - aMin);
}
}
This is a C# class. To use it from UnityScript you have to place it either in a folder called "plugins" or "Standard Assets".
You can use it like Unity's own Random class:
var someVal = DRandom.Range(-555.123d, 777.456d);
Just like Unity's Random class it also has a "value" property which just returns a double value between 0.0 and 1.0
var someVal = DRandom.value;
It also has a "seed" property. Since the System.Random class doesn't update it's seed and doesn't provide any access to the internal state of the random generator, the "seed" property just returns the seed which has been used to initialize the random generator. You can set the seed to any "int" value you like to produce always the same sequence of pseudo-random numbers. If no seed is set, the class uses the current time to calculate a seed.
Note: The values generated are not compatible with Unity's random number generator. So using the same seed in Unity's Random class won't yield the same values as this class.