Az alábbi problémába ütköztem: a feladat két koordináta távolságát kiszámolni a földgömb felületén.
az alap egyenlet (php, java, vb6-ban jól működik)
Kód: Egész kijelölése
$pi80 = 3.1415926535898 / 180;
$lat1 * = $pi80;
$lng1 * = $pi80;
$lat2 * = $pi80;
$lng2 * = $pi80;
$r = 6372.797 ; / / Mean Radius Of Earth In Km
$dlat = $lat2 - $lat1;
$dlng = $lng2 - $lng1;
$a = Sin($dlat / 2) * Sin($dlat / 2) + Cos($lat1) * Cos($lat2) * Sin($dlng / 2) * Sin($dlng / 2);
$c = 2 * Atan2(sqrt($a) , Sqrt(1 - $a));
$distance_meter = $r * $c * 1000;
Ott bukik el, hogy mikor kérem a 0.000000012 sinusát akkor az már nulla lesz mert amúgy a 0.000000000209 lenne de a vége ugye elveszik.
Próbáltam azt is hogy számítás előtt a kiinduló adatokat pl 1000-el megszorzom, így beleférek a 9 tizedesjegybe, de ha növelem a két pont távolságát úgy romlik a pontosság. És nem centiket, hanem több száz métereket.
A kérésem: hogy lehetne ezt megoldani/kikerülni?
Hajlandó vagyok az áramkörbe külön a főprocesszor mellé még egy kisebbet tenni ami soros porton beszélgetve csak ezzel foglalkozna, csak hát ugye ez nem segít a problémán...
Nem lehet pl a lebegőpontos tizedesek méretét növelni a sebesség kárára?
Vagy létezik-e olyan lib amit használva mondjuk 15 tizedesjegyig lehet a törteket ábrázolni?
Asm-ben meg lehetne írni az eljárást, több tizedesjegyre?
A példaprogram:
Kód: Egész kijelölése
'--- Alapadatok ---
$crystal = 4000000 'Sebesseg
'$regfile = "attiny45.dat" 'Chip
$regfile = "m8def.dat" 'Chip
$baud = 4800
$hwstack = 32 ' default use 32 for the hardware stack
$swstack = 32 ' default use 10 for the SW stack
$framesize = 64 ' default use 40 for the frame space
$sim
'$lib "FP_Trig.lbx"
Declare Function Tavolsag(byval Lat1 As Single , Byval Lng1 As Single , Byval Lat2 As Single , Byval Lng2 As Single) As Single
Const Dis_r = 6372.797
Const Dis_oszto = 57.2958
Const Pi = 3.1415926535898
Const Pi80 = Pi / 180
Dim Eredmeny As Single
Dim P1_1 As Single
Dim P1_2 As Single
Dim P2_1 As Single
Dim P2_2 As Single
'(
P1_1 = 46.675640
P1_2 = 17.646726
P2_1 = 46.676075
P2_2 = 17.647133
')
P1_1 = 46.678339
P1_2 = 17.614988
P2_1 = 46.676075
P2_2 = 17.647133
Do
Eredmeny = Tavolsag(p1_1 , P1_2 , P2_1 , P2_2)
'Print "er: " ; Eredmeny
'Open "comb.1:9600,8,n,1" For Output As #1
Print "text: " ; Eredmeny
'Waitms 10
'Close #1
Loop
End
Function Tavolsag(byval Lat1 As Single , Byval Lng1 As Single , Byval Lat2 As Single , Byval Lng2 As Single) As Single
'(
Ez alaján megy a számítás,
PHP, java és egyéb (PC-s) fordítókban jól működik, kb cm-es szórással ad jó eredményt
$pi80 = 3.1415926535898 / 180;
$lat1 * = $pi80;
$lng1 * = $pi80;
$lat2 * = $pi80;
$lng2 * = $pi80;
$r = 6372.797 ; / / Mean Radius Of Earth In Km
$dlat = $lat2 - $lat1;
$dlng = $lng2 - $lng1;
$a = Sin($dlat / 2) * Sin($dlat / 2) + Cos($lat1) * Cos($lat2) * Sin($dlng / 2) * Sin($dlng / 2);
$c = 2 * Atan2(sqrt($a) , Sqrt(1 - $a));
$distance_meter = $r * $c * 1000;
')
Dim E As Single
Dim Dlat As Single
Dim Dlng As Single
Dim A As Single
Dim A1 As Single
Dim A1_temp As Single
Dim A2_temp As Single
Dim A3_temp As Single
Dim B1 As Single
Dim B1_temp_1 As Single
Dim B1_temp_11 As Single
Dim B1_temp_12 As Single
Dim B1_temp_2 As Single
Dim B1_temp_3 As Single
Dim B1_temp_32 As Single
Dim C As Single
Dim C_temp_1 As Single
Dim C_temp_2 As Single
Dim C_temp_3 As Single
Lat1 = Lat1 * Pi80
Lng1 = Lng1 * Pi80
Lat2 = Lat2 * Pi80
Lng2 = Lng2 * Pi80
Print " Lat1: " ; Lat1
Print " Lng1: " ; Lng1
Print " Lat2: " ; Lat2
Print " Lng2: " ; Lng2
Dlat = Lat2 - Lat1
Dlng = Lng2 - Lng1
Dlat = Dlat * 1
Dlng = Dlng * 1
Print " Dlat: " ; Dlat
Print " Dlng: " ; Dlng
A1_temp = Dlat / 2
Print " Dlat / 2: " ; A1_temp
A2_temp = Sin(a1_temp)
Print " Sin(a1_temp): " ; A2_temp
A1 = A2_temp * A2_temp
Print " A1: " ; A1
'E = A1
B1_temp_11 = Cos(lat1)
Print " Cos(lat1): " ; B1_temp_11
B1_temp_12 = Cos(lat2)
Print " Cos(lat2): " ; B1_temp_12
B1_temp_1 = B1_temp_12 * B1_temp_11
'Print " B1_temp_1: " ; B1_temp_1
B1_temp_2 = Dlng / 2
B1_temp_32 = Sin(b1_temp_2)
Print " Sin( Dlng / 2): " ; B1_temp_1
B1_temp_3 = B1_temp_32 * B1_temp_32
B1 = B1_temp_1 * B1_temp_3
A = A1 + B1
Print " a: " ; A
C_temp_1 = Sqr(a)
C_temp_2 = 1 - A
C_temp_3 = Sqr(c_temp_2)
C = 2 * Atn2(c_temp_1 , C_temp_3)
C = C * 1000 ' méterbe átváltás
E = Dis_r * C
Tavolsag = E
End Function