![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Нужна UDF, генерирующая случайные числа [IB6.x, Firebird]
kaif © (2006-07-16 15:33:00)Имеющаяся rand делает что-то не то.
PEAKTOP (2006-07-18 13:44:00) [1]
> Johnmen © (17.07.06 20:04) [18]
> Ты думаешь, что в RFUNC реализация этих функций иная?
Не думаю. просто тема топика Нужна UDF, генерирующая случайные числа
Какой вопрос - такой ответ :))))
kaif (2006-07-17 20:19:00) [2]2 atruhin ©
В любом случае спасибо и тебе и Johnmen-у и Desdechado ©
Я как-то раньше не работал с RFUNC (страдал минимализмом).
Вижу здесь много чего полезного можно найти.
kaif (2006-07-17 20:17:00) [3]2 atruhin © (17.07.06 18:55) [16]
Значит я где-то ошибся.
У меня правда процедура была посложнее, а такой простой эксперимент не поставил - быстро начал нервничать - ничего не выходило.
Хотя по сути было почти то же, что и у тебя.
Странно.
Ладно, я еще вернусь к этой функции скоро.
Просто сейчас заново миллион записей генерировать неохота.
Я уже и так его несколько раз генерил...
Johnmen (2006-07-17 20:04:00) [4]
> PEAKTOP © (17.07.06 18:59) [17]
Ты думаешь, что в RFUNC реализация этих функций иная?
PEAKTOP (2006-07-17 18:59:00) [5]
librarymy_udf_lib;
functionmy_lib_random:extended; cdecl;
begin
Result := Random; // returns random value from 0 to 1
end;
functionmy_lib_randomize<>:longint; cdecl;
begin
Randomize;
Result := 1;
end;
exports
my_lib_random,
my_lib_randomize;
end.
---------------------------------------------------------------------------
DECLARE EXTERNAL FUNCTIONMY_RANDOM
RETURNS DOUBLE PRECISION BY VALUE
ENTRY_POINT'my_lib_random' MODULE_NAME'my_udf_lib';
DECLARE EXTERNAL FUNCTIONMY_RANDOMIZE
RETURNS DOUBLE PRECISION BY VALUE
ENTRY_POINT'my_lib_randomize' MODULE_NAME'my_udf_lib';
---------------------------------------------------------------------------
CREATE PROCEDURENEW_PROCEDURE
RETURNS(
A INTEGER,
B INTEGER,
C INTEGER
)
AS
begin
MY_RANDOMIZE;
A = IBUDF_ROUND( MY_RANDOM* 100);
B = IBUDF_ROUND( MY_RANDOM* 100);
C = IBUDF_ROUND( MY_RANDOM* 100);
SUSPEND;
END
atruhin (2006-07-17 18:55:00) [6]Работает:
A B C
49 4 86
44 12 83
56 34 86
61 61 44
0 32 43
79 13 98
6 45 61
91 92 37
43 12 28
59 59 25
kaif (2006-07-17 18:44:00) [7]2 atruhin © (17.07.06 18:14) [14]
Попробуй так:
ALTER PROCEDURE NEW_PROCEDURE
RETURNS (
A INTEGER,
B INTEGER,
C INTEGER)
AS
declare variable n integer;
begin
n = 0;
while n < 10 do
begin
a = getRANDOM(100);
b = getRANDOM(100);
c = getRANDOM(100);
suspend;
n = n + 1;
end
end
atruhin (2006-07-17 18:14:00) [8]Только что попробовал:
CREATE PROCEDURE NEW_PROCEDURE
RETURNS (
A INTEGER,
B INTEGER,
C INTEGER)
AS
begin
a = getRANDOM(100);
b = getRANDOM(100);
c = getRANDOM(100);
/* Procedure Text */
suspend;
end
Результат:
A=44; B = 4; C = 86;
kaif (2006-07-17 17:47:00) [9]Desdechado © (17.07.06 17:39) [12]
мож, я чегоне понимаю, но проще
a = GETRANDOM(1000);
вместо
SELECT GETRANDOM(1000) FROM RDB$DATABASE INTO :A;
Возможно и проще.
Просто до того я делал выборку из таблицы, в которой хранил случайные числа и мне было проще так сделать массовую замену при изменении текста процедуры.
2 Johnmen © (17.07.06 17:34) [11]
Не знаю. Я долго мучился. Вернулся к выборке из таблицы случайных чисел. Просто времени нет на эксперименты с GETRANDOM. Потом как-нибудь получше изучу поведение этой функции. INITRANDOM не спасала.
Desdechado (2006-07-17 17:39:00) [10]мож, я чегоне понимаю, но проще
a = GETRANDOM(1000);
вместо
SELECT GETRANDOM(1000) FROM RDB$DATABASE INTO :A;
Johnmen (2006-07-17 17:34:00) [11]
> kaif © (17.07.06 17:25) [10]
М.б. надо разбодяжить
SELECT GETRANDOM(1000) FROM ...
вызовами InitRandom?
kaif (2006-07-17 17:25:00) [12]2 Johnmen © (17.07.06 16:52) [9]
Нет, не забыл. С ним еще хуже.
Вот в селекте getrandom работает правильно.
Например:
SELECT GETRANDOM(1000) FROM TABLE_WITH_100_RECORDS
действительно вернет 100 случайных значений
А если написать в ХП так:
I = 0;
WHILE (I < 100) DO
BEGIN
SELECT GETRANDOM(1000) FROM RDB$DATABASE INTO :A;
SELECT GETRANDOM(1000) FROM RDB$DATABASE INTO :B;
SELECT GETRANDOM(1000) FROM RDB$DATABASE INTO :C;
END
то оказываются A=B=C
А мне нужно было как раз, чтобы они оказались разными.
(Я генерю из фамилий, имен и отчеств тестовую базу с миллионом записей.)
Johnmen (2006-07-17 16:52:00) [13]
> kaif © (17.07.06 16:46) [8]
Ашот, ты забыл InitRandom.
kaif (2006-07-17 16:46:00) [14]Странно, но внутри хранимой процедуры последовательные вызовы в цикле функции getrandom возвращают одно и то же значение. Что-то работает не так...
kaif (2006-07-17 13:25:00) [15]2 Johnmen © (16.07.06 16:29) [1]
Спасибо!
kaif (2006-07-17 13:24:00) [16]Нет, пардон, все нормально.
Просто у меня в процедуре логическая ошибка приводила к вечному циклу при некоторых значениях случайного числа.
kaif (2006-07-17 13:12:00) [17]Поставил RFUNC.
Функция GETRANDOM работает.
Но почему-то гораздо медленнее, чем моя выборка одной записи из таблицы в 100 тыс заранее подготовленных случайных чисел :(
Johnmen (2006-07-16 20:50:00) [18]
> kaif © (16.07.06 20:14) [3]
> А где можно скачать эту RFUNC?
Ну-у-у-у, Ашот..... Спроси у Яндекса, например....:)
kaif (2006-07-16 20:14:00) [19]2 Johnmen © (16.07.06 16:29) [1]
Спасибо. А где можно скачать эту RFUNC?
В принципе я выкрутился проще - загнал со стороны клиента 10 тыс записей случайных чисел [0...999] подряд в таблицу с ключом ID [0...10000]. И сейчас просто юзаю эту таблицу, состоящую из 2-х полей (ключевого и "случайного").
2 Desdechado © (16.07.06 19:35) [2]
Да просто равномерного распределения мне пока хватает.
Обычный генератор.
Если нужны особенные распределения, я просто разбиваю диапазон случайных чисел на дискретные неодинаковые по ширине поддиапазоны и так вылавливаю нужные мне распределения.
Просто то, что есть в ib_udf, вообще никуда не годится.
Она возвращает в каждом следующем SQL-запросе одно и то же значение, пока не щелкнет очередная секунда таймера, после чего функция возвращает уже следующее значение, причем следующее не в смысле случайное, а просто следующее по возрастанию номера секунды. Непонятно, кому эта функция вообще могла бы понадобиться...
Desdechado (2006-07-16 19:35:00) [20]> делает что-то не то
А что должна?
Какой закон распределения? С какими параметрами?