+135
- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
// Дефолтный конструктор:
public Random()
: this(Environment.TickCount) {
}
// Перенаправляемся сюда...
public Random(int Seed) {
int ii;
int mj, mk;
//Initialize our Seed array.
//This algorithm comes from Numerical Recipes in C (2nd Ed.)
mj = MSEED - Math.Abs(Seed);
Очередной "изящный" говнокод в исходниках .NET.
Говнокод в том, что Environment.TickCount через каждые 24,9 дней возвращает Int32.MinValue, который скормится Math.Abs, который резонно выкинет исключение OverflowException. Вроде бы мелочь, но... Вспомним теперь падение .NET-софта на Лондонской бирже и последующие миллионные убытки. Для загруженных non-stop-серверов непростительно. Хотя в принципе Microsoft аптаймами и не славился :)
Запостил:
cfdev,
27 Апреля 2010
И опять же кстати категорически непонятно почему Environment.TickCount может быть отрицательным.
Короче странный он этот .NET %)
Что значит "по идее"? Для Int32.MinValue нет соответствующего позитивного значения, т.к. целые числа кодируются неортогонально: MinValue = -2147483648, в то время как MaxValue = 2147483647.
msdn конечно же нигде не указывает, что Random() теоретически может выкинуть исключение. Стабильная, надёждная managed-платформа :)
> И опять же кстати категорически непонятно почему Environment.TickCount может быть отрицательным
К этому же вопросу: почему индексы у массивов имеют тип int, а не uint? Ответ скорей всего кроется в том, что .NET создана из кусков трупа J++, а в java нет uint...
скорей всего, см. 2 пункт про J++ или просто конвеншон: "какой тип получаем, такой и должны возвратить"
long Abs(long);
int Abs(int);
short Abs(short);
В джаве еще кстати, оказывается, нет int8 и int16 - ну, то есть, они как бы есть, но внутри это все равно всегда int32 %)
В НЕТе всякие uint32 сделаны, похоже, чисто для PInvoke
А какими они ещё должны быть на 32-разрядной платформе?
А то что ж это получается, мне для того, чтобы завести массив флагов, надо на каждый элемент четыре байта потратить?
Про выравнивание я знаю, спасибо.
2. Эксепшена не будет.
3. Код полностью нормальный.
http://www.rsdn.ru/forum/dotnet/1509710.flat.aspx
Math.Abs(-2147483648)==2147483648, но это не возможно, так как предельное значение int32 = 2147483647. Overflow Exception.
Что-за велосипед?
2. Эксепшн будет
3. Код нормальный, потому что Environment.TickCount не возвращает int.MinValue
The value of this property is derived from the system timer and is stored as a 32-bit signed integer. Consequently, if the system runs continuously, TickCount will increment from zero to Int32..::.MaxValue for approximately 24.9 days, then jump to Int32..::.MinValue, which is a negative number, then increment back to zero during the next 24.9 days.
3. Код не нормальный, потому что Environment.TickCount возвращает int.MinValue.
Зачем - одному Б-гу известно.
Ага. Всегда возвращает. Каждую секунду Environment.TickCount==int.MinValue.
Ага, но твой код упадет в самый неподходящий момент.
с вероятностью 1/2^32 вы получите эксепшн
это объясняет многие случайные глюки других продуктов Микрософта :D
но не было.
Было:
Стало:
public Random(int Seed)
{
this.SeedArray = new int[56];
base.ctor();
int num1 = 161803398 - (Seed == int.MinValue ? int.MaxValue : Math.Abs(Seed));
//...