Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailemVyřešeno Problém s NAN v nových Delphi

Dobrý deň, mám aplikáciu, ktorá počíta na základe gps súradníc vzdialenosti medzi gps bodmi, prípadne cieľový bod od počiatočného bodu v zadanom smere a vzdialenosti. Výpočet nového bodu sa robí takouto funkciou:

Procedure Rhumb1(LAT1,LON1, Azimuth1, Dist:EXTENDED; VAR LAT2, LON2:EXTENDED);
 var
   sig, DLat, PDLat, q, DLon:extended;
 begin
sig:=Dist/(1000*ERad);
   DLat:=sig*cos(azimuth1);
   Lat2:=Lat1+DLat;
PDLat:=ln(tan(Pi/4+Lat2/2)/tan(Pi/4+Lat1/2));
   if PDLat>1e-12 then Q:=DLat /PDLat else Q:=cos(lat1);
   DLon:=sig*sin(Azimuth1)/Q;
   Lon2:=Lon1+DLon;
 end;

Riadok

PDLat:=ln(tan(Pi/4+Lat2/2)/tan(Pi/4+Lat1/2));

je problematický, pretože v niektorých situáciách nevráti korektný výsledok a vtedy sa ocitáme mimo našej matičky zeme. V starom prostredí Delphi 6 som s tým nemal problém, pretože daný riadok vrátil hodnotu NAN a rovnako tak výsledok lon2 bol NAN takže kdekoľvek v programe po zavolaní tejto procedúry bolo možné urobiť if isnan(lon2) then 'mimo mapu'. V nových Delphi XE8 a 10 však občas program na danom riadku spadne a ak aplikáciu skompilujem na 64 bit, spadne úplne vždy. Viem že existuje možnosť dať to celé do try exception a sledovať kedy došlo k chybe, no zdá sa mi to ako dosť neomalené amatérske riešenie a tak sa chcem opýtať, prečo majú Windows s týmto problém resp ako to nejako riešiť. Skúšal som si na webe nájsť nejaké riešenie a vidím, že s hodnotou NAN je nejaký problém no nenarazil som na žiadne funkčné riešenie. Vďaka

Předmět Autor Datum
Niečo bude asi mimo rozsah, nie? Máš tam funkcie, delenie. Treba to ošetriť.
čitateľ 31.10.2016 12:39
čitateľ
Tak si před výpočtem zkontroluj hodnoty argumentů funkce TAN (tedy Pi/4+Lat2/2 a Pi/4+Lat1/2) a pak…
Machr55 31.10.2016 13:16
Machr55
Matematika nie je moja silná stránka, preto sa pýtam: určite sa to takto počíta, máš ten vzorec sprá…
pme 31.10.2016 18:03
pme
Dobrý večer, ani ja sa až natoľko nevyznám v matematike, aby som porozumel podstate tohto výpočtu. D…
Stefan77 31.10.2016 22:21
Stefan77
... vzorec vráti NAN a ja viem, že výsledok nie je platným bodom na Zemi a príslušne ho spracujem...…
Machr55 01.11.2016 07:53
Machr55
Ako si správne napísal, máš aplikáciu. Ale nemáš program.
čitateľ 01.11.2016 09:05
čitateľ
toto ma aky vyzname pri tomto probleme? Preco pises bludy bez logiky? Vrat sa az budes triezvy. Vie… poslední
shiro 01.11.2016 09:47
shiro

Dobrý večer, ani ja sa až natoľko nevyznám v matematike, aby som porozumel podstate tohto výpočtu. Dlho som však hľadal spôsob, ako podľa súradníc jedného bodu na zemi podľa vzdialenosti a smeru vyrátať druhý a tento vzorec presne toto robí a určite počíta správne. Vstupné parametre sú lat a lon nejakého bodu na zemi (v radiánoch), azimut (tiež v radiánoch) a vzdialenosť v metroch. Takže ak ako vstup zadáme napr. súradnice Bratislavy deg2rad(48.125), deg2rad(17.070), azimut deg2rad(0) a vzdialenosť 100000, dostaneme výsledok 49.023 17.070
(samozrejme oboje po prevode z radiánov na stupne) a to je bod 100 Km severne od Bratislavy. Vzorec však nemá ošetrené napr. preklopenie cez pól a to musím teda robiť ručne. Ak z tohto vzorca matematicky vyjde latitúda väčšia ako 90 alebo premenná lon2 je bez numerickej hodnoty NAN, tak viem, že treba výsledok ošetriť. No a tu je práve ten problém. V 32-bitovej aplikácii vzorec vráti NAN a ja viem, že výsledok nie je platným bodom na Zemi a príslušne ho spracujem. 64-bitová aplikácia však na tom kritickom riadku spadne s nejakou hláškou o chybe pri float operation a ja sa už ani nedostanem k tomu, aby som výsledok nejako ošetril. Skúsil som pridať direktívu
{$FINITEFLOAT OFF}
ktorá by mala vypnúť kontrolu float operácií, ale nepomohlo to. Teda chyba nie je vo výpočte samom ale v tom, že ja by som potreboval odchytiť že je vrátený žiadny výsledok. Nechápem prečo 32-bit s tým nemá problém a 64-bit spadne - občas aj 32-bit ale len výnimočne. A ide mi skôr o to, či sa nedá stav zo starých Delphi dosiahnuť nejakou konfiguráciou. Dočítal som sa na nete o viacerých typoch NAN ale veľmi som tomu neporozumel. Zatiaľ som celý vzorec dal do try a exception ale keďže ide o jadro programu, je tento výpočet volaný veľmi často a po nejakom čase skôr či neskôr aj tak aplikácia spadne, ak je exception vyvolaná opakovane niekoľko sto alebo tisíckrát. Takže rátať s chybou a nechať ju vyvolávať cyklycky do kola mám pocit nie je to pravé riešenie.

... vzorec vráti NAN a ja viem, že výsledok nie je platným bodom na Zemi a príslušne ho spracujem...

To jako vážně programuješ tak, že něco zkusíš zavolat, a když to nevyjde, tak to zpracuješ jinak? :-?
Psal jsem výše, aby sis ještě před samotným výpočtem zkontroloval hodnoty argumentů a dle toho se zařídil. To je jediný možný a správný postup!

toto ma aky vyzname pri tomto probleme? Preco pises bludy bez logiky? Vrat sa az budes triezvy.

Viem že existuje možnosť dať to celé do try exception a sledovať kedy došlo k chybe, no zdá sa mi to ako dosť neomalené amatérske riešenie

ano a preto to checkujes ako posledny amater a spoliehas sa na nejaky systemovy vymysel vracajuci tri pismenka :D Super.

Ako programator mas davno vediet ze s kazdou verziou hocijakeho OS sa toto chovanie moze zmenit a tudiz si si nicim nie isty. Obzvlast ma absencia takehoto rozmyslania a elementarnej logiky prekvapiuje pri niekom, kto programuje zrovna GPS appku, co neni nic lahkeho. Tudiz cakam ze to bude robit vyzrety clovek, ktory rozmysla.

Skratka si na toto urob check niekde v programe, nespoliehaj sa na system ci nejaky obecny vysledok funkcie. Je zaujimave ze sa k 64bit stavias ako k dacomu, co vidis mozno len ako "natiahnutie" registrov na dvojnasobok oproti 32bit. Ziadne take, su tam aj ine zmeny a je ich kopa.

A co delphi dokumentacia, tam si hladat skusal, ze ako sa to spracovava? Prve miesto, kde by som pozeral a nie na fora kadetade.

Zpět do poradny Odpovědět na původní otázku Nahoru