Невозможно неявно преобразовать тип «длинный» в «улонг». (+случайный улонг)

Я объявлял класс с параметром ulong, но когда я хочу не присвоить его в конструкторе, программа говорит мне, что что-то не так, но я не понимаю, что. Это улонг, я не хочу, чтобы он что-то конвертировал.

public class new_class
{
    ulong data;
    new_class()
    {
        Random rnd = new Random();
        data = rnd.Next() * 4294967296 + rnd.Next(); //4294967296 = 2^32
    }
}

бонусные баллы, если вы можете сказать мне, правильно ли это объявление случайного ulong, оно должно сначала рандомизировать int (32 бита) и сохранить их в первых 32 битах ulong, затем создать новое случайное число и сохранить их во вторых 32 битах.


person Orodshsen    schedule 06.05.2014    source источник
comment
Random.Next возвращает положительный (но подписанный) int. Вы должны передать его на ulong.   -  person Blorgbeard    schedule 06.05.2014


Ответы (2)


Random.Next() генерирует только 31 бит истинной случайности:

32-разрядное целое число со знаком, большее или равное нулю и меньшее, чем MaxValue.

Поскольку результат всегда положительный, старший бит всегда равен 0.

Вы можете сгенерировать два int и объединить их, чтобы получить число с 62-битной случайностью:

data = ((ulong)rnd.Next() << 32) + rnd.Next();

Если вам нужны 64 бита случайности, другой метод — сгенерировать 8 случайных байтов, используя GetBytes:

byte[] buffer = new byte[8];
rnd.NextBytes(buffer);
data = BitConverter.ToUInt64(buffer, 0);
person D Stanley    schedule 06.05.2014

Проблема здесь в том, что вы получаете long в результате вашего выражения. Сообщение об ошибке должно прояснить это:

Невозможно неявно преобразовать тип «длинный» в «улонг». Существует явное преобразование (вам не хватает приведения?)

Вам пришлось бы явно привести результат к ulong, чтобы присвоить его data, что делает его

data = ((ulong) ( rnd.Next() * 4294967296 + rnd.Next() ) ;

Однако ваше намерение было бы более ясным, если бы вы просто сдвигали биты:

ulong data = ( ((ulong)rng.Next()) << 32 )
           | ( ((ulong)rng.Next()) <<  0 )
           ;

Это также было бы быстрее, поскольку битовые сдвиги - гораздо более простая операция, чем умножение.

person Nicholas Carey    schedule 06.05.2014
comment
Операция не будет намного быстрее. Процессоры достаточно быстрые, а компиляторы достаточно умные. Но это будет гораздо более читабельно, и это достаточная причина для изменения, а не для добавления. - person Maarten Bodewes; 27.07.2018