Может кто-нибудь проверить этот метод. Мне нужен длинный номер в диапазоне двух длинных чисел. Я использую функцию .NET Random.Next (min, max), которая возвращает int. Верны ли мои рассуждения, если я просто делю длинное число на 2, генерирую случайное число и, наконец, снова умножаю его на 2? Или я слишком в восторге ... Я понимаю, что мое случайное разрешение уменьшится, но есть ли другие ошибки, которые не приведут к получению такого случайного числа.
long min = st.MinimumTime.Ticks; //long is Signed 64-bit integer
long max = st.MaximumTime.Ticks;
int minInt = (int) (min / 2); //int is Signed 64-bit integer
int maxInt = (int) (max / 2); //int is Signed 64-bit integer
Random random = new Random();
int randomInt = random.Next(minInt, maxInt);
long randomLong = (randomInt * 2);
Я записал приложение консоли C# сравнительного тестирования, которое тестирует 5 различных методов на генерацию неподписанных 64-разрядных целых чисел. Некоторые из тех методов упомянуты выше. Метод № 5, казалось, последовательно был самым быстрым. Я утверждаю, что не был никаким гением кодирования, но если это помогает Вам, Вы можете брать. Если у Вас есть лучшие идеи, отправьте. - Dave (sbda26@gmail.com)
enter code here
static private Random _clsRandom = new Random();
private const int _ciIterations = 100000;
static void Main(string[] args)
{
RunMethod(Method1);
RunMethod(Method2);
RunMethod(Method3);
RunMethod(Method4);
RunMethod(Method5);
Console.ReadLine();
}
static void RunMethod(Func<ulong> MethodX)
{
ulong ulResult;
DateTime dtStart;
TimeSpan ts;
Console.WriteLine("--------------------------------------------");
Console.WriteLine(MethodX.Method.Name);
dtStart = DateTime.Now;
for (int x = 1; x <= _ciIterations; x++)
ulResult = MethodX.Invoke();
ts = DateTime.Now - dtStart;
Console.WriteLine(string.Format("Elapsed time: {0} milliseconds", ts.TotalMilliseconds));
}
static ulong Method1()
{
int x1 = _clsRandom.Next(int.MinValue, int.MaxValue);
int x2 = _clsRandom.Next(int.MinValue, int.MaxValue);
ulong y;
// lines must be separated or result won't go past 2^32
y = (uint)x1;
y = y << 32;
y = y | (uint)x2;
return y;
}
static ulong Method2()
{
ulong ulResult = 0;
for(int iPower = 0; iPower < 64; iPower++)
{
double dRandom = _clsRandom.NextDouble();
if(dRandom > 0.5)
{
double dValue = Math.Pow(2, iPower);
ulong ulValue = Convert.ToUInt64(dValue);
ulResult = ulResult | ulValue;
}
}
return ulResult;
}
static ulong Method3() // only difference between #3 and #2 is that this one (#3) uses .Next() instead of .NextDouble()
{
ulong ulResult = 0;
for (int iPower = 0; iPower < 64; iPower++)
if (_clsRandom.Next(0, 1) == 1)
ulResult = ulResult | Convert.ToUInt64(Math.Pow(2, iPower));
return ulResult;
}
static ulong Method4()
{
byte[] arr_bt = new byte[8];
ulong ulResult;
_clsRandom.NextBytes(arr_bt);
ulResult = BitConverter.ToUInt64(arr_bt, 0);
return ulResult;
}
// Next method courtesy of https://stackoverflow.com/questions/14708778/how-to-convert-unsigned-integer-to-signed-integer-without-overflowexception/39107847
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Explicit)]
struct EvilUnion
{
[System.Runtime.InteropServices.FieldOffset(0)] public int Int32;
[System.Runtime.InteropServices.FieldOffset(0)] public uint UInt32;
}
static ulong Method5()
{
var evil = new EvilUnion();
ulong ulResult = 0;
evil.Int32 = _clsRandom.Next(int.MinValue, int.MaxValue);
ulResult = evil.UInt32;
ulResult = ulResult << 32;
evil.Int32 = _clsRandom.Next(int.MinValue, int.MaxValue);
ulResult = ulResult | evil.UInt32;
return ulResult;
}
}