Czy to możliwe , że pascal żle liczy?

0
[pascal]
procedure F_licz;
var
y,x,h,dlugosc:integer;
Xc,Yc,poleC,polePoj,Sx,Sy,Ix,Iy:real;
Mxc:real;
Myc:real;
komunikat,s,load:string;
plik: text;
begin
schowajMyche;
 y:=20;
 dlugosc:=0;
 Sx:=0;
 Sy:=0;
 poleC:=0;
 polePoj:=0;
 Ix:=0;
 Iy:=0;
 Mxc:=0;
 Myc:=0;
 h:=1;{wysokosc prostokat i skok}
 outTextXY(230,getMaxY-15,'#LICZ!!!#');
 repeat

  for x:=0 to (getMaxX-10) do
  begin

   if getPixel(x,y)=green then   {jezeli natrafilismy na obszar przemiotu}
   begin
    while getPixel(x,y)=green do
    begin
    { putPixel(x,y+1,1);   {rysowanie lini podzialu}
     putPixel(x,y,3);
     dlugosc:=dlugosc+1;
     x:=x+1;
    end;

    Xc:=x-1-( dlugosc/2 ) ; {srodek ciezkosci}
    Yc:=(y-0.5);
    polePoj:=(dlugosc)*h;  {dlugosc*h powierzchnia pojedynczego prost}
    Sx:=Sx+ Yc * polePoj; {Sx,Sy to momety statyczne}
    Sy:=Sy+ Xc * polePoj;
    poleC:=poleC+polePoj; {pole calkowite figury}
    Ix:=Ix+( dlugosc*h*h*h /(12) )+( sqr(Yc)*polePoj );{momet bezwladnosci wzgledem x}
    Iy:=Iy+( h*sqr(dlugosc)*dlugosc /(12) )+( sqr(Xc)*polePoj );{/5 i /25 przescie na milimetry}
   end;
   dlugosc:=0; {zerowanie podstawy prost. przed liczeniem nastepnego}
   polePoj:=0;
  end;
  {-----------------------------------------}
  if (y mod 20 )=0 then {wyswietlanie ladowania}
   begin
    load:=load+'|';
    outTextXY(310,getMaxY-15,load);
   end;
 {------------------------------}
  y:=y+h;   {skok ,wysokosc prostokata}
 until y>(getMaxY-20); {wyjscie z petli sprawdzajacej}

 assign(plik,'c:/obserwuj1.txt');
 rewrite(plik);

 Xc:=Sy/poleC;  {srodek ciezkosci w pixelach}
 Yc:=Sx/poleC;
 Mxc:=0;
 Myc:=0;
 Mxc:=Ix- Yc*Yc*poleC ;  {momenty bezwladnoasci centralne}
 Myc:=Iy- Xc*Xc*poleC ;  {tw. steinera}
 {Ixc:=Ixc/625;   {przejscie na milimetry^4}
 {Iyc:=Iyc/625;   }
{ str(Xc/5:3:3,s); {Xc/5 przejscie na milimetry}
{ komunikat:='Xc='+s+' Yc=';
 str(Yc/5:3:3,s);
 komunikat:=komunikat+s;
 outTextXY(40,30,komunikat);
 str(Ixc^:9:3,s);
 komunikat:='Ixc='+s+' Iyc=';  {laczenie numerycznego z stringiem}
 {str(Iyc^:9:3,s);
 komunikat:=komunikat+s;
 outTextXY(40,40,komunikat); }
 setColor(12);
 circle(round(Xc),round(Yc),2);   {rysowanie srodka}
 wybur:=pusty;
 pokazMyche;
 {-------------------------------}
 setColor(blue);               {mazanie loadera i komunikatu}
 outTextXY(310,getMaxY-15,load);
 outTextXY(230,getMaxY-15,'#LICZ!!!#');
 {---------------------------------------}
 writeln(plik,'xc ',xc:9:3);
 writeln(plik,'yc ',yc:9:3);
 writeln(plik,'ix ',ix:9:3);
 writeln(plik,'iy ',iy:9:3);
 writeln(plik,'ixc ',Mxc:9:3);
 writeln(plik,'iyc ',Myc:9:3);
 writeln(plik,'pole cal ',poleC:8:3);
 close(plik);
end;
{*************************************}
[pascal]

Nie moge <ort>rozgrysc </ort>przyczyny dlaczego w fragmencie gdzie sa liczone centralne momenty bezwladnosci
moment Myc wychodzi ujemny choc nie powinien bo oba momenty powinny byc tego samego rzedu czyli dodatni. wychodzi ort! ze program wykonuje obliczenia w ten oto sposób np.:
wyniki:
xc 265.500
yc 260.500
ix 333671249.670
iy 344606930.330
Mxc 1902487.417
Myc -19901.916
pole cal 4889.000
czyli
-19901.916= 344606930.330- 260.500^2*4889.000
co jest kompletną bzdurą.
Za pomoc dziekuje!!!

0

wklepałem takie coś

uses crt;

var x, y, z, q :real;

begin

ClrScr;
x := 0;

y := 344606930;
z := 260.5;
q := 4889.0;

x := 344606930 - 260.5*260.5 * 4889;


writeln(x :0 :0);

x := y - z*z * q;
writeln(x :0 :0);

readln;
end.

U mnie x podaje wynik 12898167.75. Musisz mieć gdzieś błąd w obliczeniach wcześniej. Sprawdź debuggerem jakie wartości przyjmują poszczególne zmienne i czy są one zgodne z danymi, które obliczyłeś ręcznie. Pisałem wiele takich programów i zawsze miałem błąd typu + zamisat - itp.

Nie to raczej niemożliwe. Szybciej błędy na którymś z miejsc po przecinku, ale nie taka różnica. Napisz prgram: WriteLn(2+2) i będziesz wiedział. Jak da cztery to ok, jak nie to masz problem.

0

Nie sprawdzałem poprawności wpisanych wzorów, ale widzę gdzie możesz mieć błąd (nie dotyczący postaci wzorów).

Co do poprawności liczenia, to masz rację - pascal źle liczy - ale tylko w tym przypadku, bo sam mu tak kazałeś ;) Zaufaj, że on nie zrobi nic czego mu nie będziesz kazał - po prostu czegoś nie przewidziałeś.

W linii Ix:=Ix+( dlugosc*h*h*h /(12) )+( sqr(Yc)*polePoj ); byłby błąd gdyby h<>0, ale widzę, że h stale =1 więc do tego nie będę się czepiać.
Ale tutaj: Iy:=Iy+( h*sqr(dlugosc)*dlugosc /(12) )+( sqr(Xc)*polePoj ); występuje błąd przepełnienia: otóż masz tutaj sqr(dlugosc)*dlugosc czyli dlugosc3 - integer może pomieścić maksymalną wartość =32767, więc już przy dlugosc =32 nastąpi przepełnienie. Dzieje się tak dlatego, bo program najpierw pamięta wartość dlugosc3 w typie integer i dopiero tą wartość podstawia do wzoru. Więc proponuję wpisać coś w stylu r :=dlugosc; r :=r *dlugosc i potem jeszcze raz r :=r *dlugosc i będzie w porządku - r będzie przechowywać prawidłową wartość dlugosc^3, a dopiero potem wstawić ją do wzoru (r : real). Ale najłatwiej byłoby po prostu zadeklarować x, y, z, h, dlugosc jako real i jestem pewien, że nie będzie problemu z wynikami.

Pozdrawiam.

0

Niestety przykro mi bardzo ale nie w tym problem. Bo momenty które wymieniłeś sa liczone poprawnie, natomiast błędy sie pojawiają przy momemtach centralnych Mxc i Myc.
Pozdrawiam!!!

0
leonpar napisał(a)
 Mxc:=Ix- Yc*Yc*poleC ;  {momenty bezwladnoasci centralne}
 Myc:=Iy- Xc*Xc*poleC ;  {tw. steinera}

xc 265.500
yc 260.500
ix 333671249.670
iy 344606930.330
Mxc 1902487.417
Myc -19901.916
pole cal 4889.000
czyli
-19901.916= 344606930.330- 260.500^2*4889.000
co jest kompletną bzdurą.
Za pomoc dziekuje!!!

...
Ok, w takim razie masz błąd we wzorach jednak...
Zauważ, że -19901.916= 344606930.330- 265.500^2*4889.000 JEST PRAWDĄ.
W kodzie masz we wzorze xc =265.5, a sprawdzasz z liczbą yc=260.5. Wyszło na błąd programisty, nie kompilatora.

Mimo wszystko pozdrawiam ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1