![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
![]() Необходимо смоделировать случайную потерю электроном при соударении с атомом. Случайная потеря энергии моделируется функцией:
Код:
Function EL(i:Integer):Real; begin Randomize; gamma:=roundto((random),-3); //псевдослучайное число En:=0; for i:=0 to 20000 do begin En:=Ep*(1+i/20); // приращение энергии от 1 эВ с шагом i/20 if (Gx(En)=gamma) then EL:=(En/Ep); // Gx(En) - это функция задающая вероятность величины потери энергии (до 3 знака) end; end; Энергия которая осталась у электрона после потери считается так: Function Energy(j:Integer):Extended; begin if j=1 then Energy:=E/Ep; if (j>1) then Energy:=Abs(Energy(j-1)-EL(j)); end; Проблема: если среди значений En не нашлось с точностью до 3 знака равного gamma, то программа вылетает, сообщая что Energy(j) = NaN. Пожалуйста, помогите дописать алгоритм так чтобы не возникало неопределенности Последний раз редактировалось Admin, 03.07.2012 в 09:57. |
#2
|
||||
|
||||
![]() а что компилятор не выдает предупреждение:
Цитата:
Пишу программы за еду. __________________ |
#3
|
|||
|
|||
![]() Цитата:
Не выдает. Суть в том, что для, грубо говоря, 1000 электронов все нормально считается - но стоит попытаться посчитать для большего числа-скажем, для 3000, программа вылетает с ошибкой: "Project Scattering.exe raised exeption class EInvalidOp with message: 'Invalid floating point operation'. Process stopped. Use Step or Run to continue" |
#4
|
|||
|
|||
![]() Ну во первых:
Вызов Randomize вынести из EL, она должна вызываться один раз при старте программы. Во вторых: Что произойдет, если в 9-ой строке ни один Gx(en) на буден равен gamma, то есть присваивание ниразу не выполнится? У Вас скорее всего такой случай. |
#5
|
|||
|
|||
![]() Код:
if (Gx(En)=gamma) then EL:=(En/Ep); Вот после этого думаю надо добавить проверку на случай, если Gx(En)<>gamma А точнее в самом начале функции присвоить Result какое-то значение. Можно еще все это дело забабахать в еще один цикл while/repeat который выполняется пока не будет достигнуто условие Gx(En)=gamma. Сбособ конечно ужасный, но больше ничего не могу предложить. Если уж совсем жалко процессорного времени, то можно и сделать огранчение на кол-во итераций цикла. Но опять же придется задавать значение при невыполнении условий. |
Этот пользователь сказал Спасибо Arvo за это полезное сообщение: | ||
ZolotukhinDen (10.07.2012)
|
#6
|
|||
|
|||
![]() Цитата:
Вообще-то сооовсем не обязательно. Randomize устанавливает переменную RandSeed, которая используется как случайные данные при генерации псевдослучайных чисел. Точно не знаю, но вроде она берет значение системного таймера. Можно не вызывать randomize, а самому установить RandSeed. Randomize следует вызывать каждый раз, когда надо получить новую серию псевдослучайных чисел.- |
#7
|
||||
|
||||
![]() Цитата:
в любом случае сделай чтобы Energy всегда что-то возвращала, либо Exception. Пишу программы за еду. __________________ |
#8
|
||||
|
||||
![]() Интересные рассчеты. Во-первых,
Цитата:
Во-вторых, зачем передавать в функцию El() параметр i, если он внутри пробегает значения Цитата:
|
#9
|
|||
|
|||
![]() Цитата:
|
#10
|
|||
|
|||
![]() [OFFTOP]Вот так потом ядерные реакторы и работают.
![]() |