Переполнение плавающей точкой. Где ошибка в программе? - Pascal
Формулировка задачи:
Program U2ITELb;
Uses graph, crt;
Const
w1:real=1e8;
w:real=1e7;
l:real=0.2;
w0:real=2e-8;{sobsvetna chastota kolebanyu}
A1:real=3;
pt:real=2.5e-8;
tm:real=36e-6;
dt:real=0.5e-8;
dtau:real=0.2e-8;
m:real=0.3;
Var
t,tau,y:real;
z,g:integer;
driver,mode:integer;
function U1(t:real):real;
begin
U1:=A1*(1+m*sin(w*t))*sin(w1*t);
end;
function h(t:real):real;
begin
h:=(1-1*exp(-t/pt))*(cos(w0*t)+l*sin(w0*t));
end;
Begin
driver:=detect;
initgraph(driver,mode,' ');
line(10,10,10,470);
line(10,240,630,240);
moveto(10,240);
t:=0;tau:=0;
repeat
y:=0;
if t>(3*tau) then tau:=t-(3*tau) else tau:=0;
repeat
y:=y+abs(U1(tau))*h(t-tau)*dtau;
tau:=tau+dtau;
until tau>t;
t:=t+dt;
z:=10+round(600/tm*t);
g:=240-round(100*y);
lineto(z,g);
until t>tm;
readln;
END.Решение задачи: «Переполнение плавающей точкой. Где ошибка в программе?»
textual
Листинг программы
uses graph;
const
w1:real=1e+8; {sobstvenni kolebaniy}
tm:real=10e-9; {vremya modelirovaniya}
dt:real=1e-9; {shag modelirovaniya}
n:integer=2; {kol-vo uravneniy}
dk:real=0.0001; {masshtabnyi koef-t}
ti:real=1e-8;{metka}
u1:real=1e+7;
T1:real=0.5e-8;
T2:real=0.2e-8;
type
vec=array[1..2] of real;
matr=array[1..4,1..2] of real;
proc1=procedure(n:integer;var y,dy:vec);
proc2=procedure(n:integer;dt:real;var y,dy:vec;var ier:boolean);
var
i,j,driver,mode,x,z:integer;
ier:boolean;
y,dy:vec;
w2,d,t,f:real;
procedure fct(n:integer;var y,dy:vec) ;far;
begin
f:=sqr(3*(1+0.7*sin(u1*t))*(sin(w1*t)));
dy[1]:=y[2];
dy[2]:=(f-y[1]-y[2]*T2)/(T1*T1);
end;
procedure out(n:integer;dt:real;var y,dy:vec;var ier:boolean); far;
begin
t:=t+dt; {shag vremeny}
if t>tm then ier:=true;
x:=10+round(620/tm*t);
z:=240-round(dk*y[1]);
lineto(x,z);
end;
procedure rk4(n:integer;ier:boolean;h:real;fct:proc1;out:proc2;var y,dy:vec);
var
c:vec;
k:matr;
i,j:integer;
begin
repeat
c:=y;
for i:=1 to 4 do begin
fct (n,y,dy);
for j:=1 to n do begin
k[i,j]:=dy[j]*h;
case i of
3: y[j]:=c[j]+k[i,j];
4: y[j]:=c[j]+(k[1,j]+2*k[2,j]+2*k[3,j]+k[4,j])/6
else y[j]:=c[j]+0.5*k[i,j];
end;end;end;
out (n,h,y,dy,ier);
until ier;
end;
begin
ier:=false;
t:=0; y[1]:=0; y[2]:=0; f:=1/dt;
driver:=detect;
initgraph (driver,mode,'');
line(10,10,10,480);
line(10,240,640,240);
moveto(10,240);
for i:=0 to 10 do begin
x:=10+i*round(620/tm*ti);
line(x,(240-10),x,(240+10));
for j:=1 to 9 do begin
line(x+round(620/tm*ti*0.1*j),(240-5),x+round(620/tm*0.1*ti*j),(240+5));
end;end;
rk4(n,ier,dt,fct,out,y,dy);
readln;
end.
Объяснение кода листинга программы
- Переменная
tmиспользуется в качестве временного шага для моделирования, она должна быть больше максимального времени, необходимого для выполнения одного полного оборота колеса. Если это условие не выполняется, то возможны переполнения при вычисленииtв процедуреout. - Переменная
dtиспользуется в качестве шага по времени для четвертого порядка Рунге-Кутты. Она должна быть меньшеtm, чтобы избежать переполнений при вычисленииtв процедуреout. - Переменная
dkиспользуется в качестве коэффициента дискретности. Если она слишком большая, то это может привести к неточным результатам из-за эффекта дискретности. - Переменная
u1используется в формуле для генерации синусоидального сигнала. Если ее значение слишком большое, то это может привести к неточным результатам из-за эффекта округления. - Переменная
T1используется в формуле для генерации синусоидального сигнала. Если ее значение слишком большое, то это может привести к неточным результатам из-за эффекта округления. - Переменная
T2используется в формуле для генерации синусоидального сигнала. Если ее значение слишком большое, то это может привести к неточным результатам из-за эффекта округления. - Переменная
w1используется в формуле для генерации синусоидального сигнала. Если ее значение слишком большое, то это может привести к неточным результатам из-за эффекта округления. - Переменная
w2используется в формуле для генерации синусоидального сигнала. Если ее значение слишком большое, то это может привести к неточным результатам из-за эффекта округления. - Переменная
fиспользуется в формуле для вычисления силы. Если ее значение слишком большое, то это может привести к неточным результатам из-за эффекта округления. - Переменная
dиспользуется в формуле для вычисления силы. Если ее значение слишком большое, то это может привести к неточным результатам из-за эффекта округления. - Переменная
tиспользуется в формуле для вычисления времени. Если ее значение слишком большое, то это может привести к неточным результатам из-за эффекта округления. - Переменная
xиспользуется для вычисления позиции колеса. Если ее значение слишком большое, то это может привести к неточным результатам из-за эффекта округления. - Переменная
zиспользуется для вычисления позиции колеса. Если ее значение слишком большое, то это может привести к неточным результатам из-за эффекта округления. - Переменная
yиспользуется для хранения текущих значений координат колеса. Если ее значение слишком большое, то это может привести к неточным результатам из-за эффекта округления. - Переменная
dyиспользуется для хранения текущих значений скоростей координат колеса. Если ее значение слишком большое, то это может привести к неточным результатам из-за эффекта округления. - Переменная
cиспользуется в формуле для вычисления следующей позиции колеса. Если ее значение слишком большое, то это может привести к неточным результатам из-за эффекта округления. - Переменная
kиспользуется в формуле для вычисления следующей позиции колеса. Если ее значение слишком большое, то это может привести к неточным результатам из-за эффекта округления. - Переменная
iиспользуется в цикле для вычисления следующей позиции колеса. Если ее значение слишком большое, то это может привести к неточным результатам из-за эффекта округления. - Переменная
jиспользуется в цикле для вычисления следующей позиции колеса. Если ее значение слишком большое, то это может привести к неточным результатам из-за эффекта округления. - Переменная
ierиспользуется для контроля выхода из цикла. Если ее значение слишком большое, то это может привести к неточным результатам из-за эффекта округления.