Distance( constref pt0,pt1:TDVec2 ):double;
var cp,st:TDVec2;
sin_sr1,sin_sr2,
cos_sr1,cos_sr2,v:double;
begin
cp := radians( pt0 );
st := radians( pt1 );
sin_sr1 := sin( st.lat );
sin_sr2 := sin( cp.lat );
cos_sr1 := cos( st.lat );
cos_sr2 := cos( cp.lat );
v := clamp( sin_sr1*sin_sr2 + cos_sr1*cos_sr2 * cos( st.lng-cp.lng ), 0.0, 1.0 );
Result := Rearth*arccos( v );
end;
Тоже самое я реализовал на OpenCL и выяснил что OpenCL считает чуть точнее:
distCPU[4] = 0.0000949369370937348
distCPU[5] = 0.0000949369370937348
distCPU[6] = 0.00018987387418747
distCPU[7] = 0.00018987387418747
distCPU[8] = 0.000232547053622355
distCPU[9] = 0.000232547053622355
distCPU[10] = 0.000268522208016242
distCPU[11] = 0.000268522208016242
distCL[4] = 0.0000949369370937347
distCL[5] = 0.000134261104008121
distCL[6] = 0.000164435598561319
distCL[7] = 0.000189873874187469
distCL[8] = 0.000212285444917212
distCL[9] = 0.000251179525784205
distCL[10] = 0.000284810811281204
distCL[11] = 0.000300216955296328
double считает процессор. ему пофиг какой язык. а вот тот же синус это библиотечная функция и может иметь разную точность.
Что можно сделать чтобы посчитать sin/cos/arcos максимально точно?
Если нужно считать расстояния между атомами в разных галактиках, то лучше использовать не Double, а что-то из библиотек для математиков. У Double не десятичная плавающаа точка, а двоичная, поэтому арифметика сильно хромает.
Тут ещё можно sin+cos заменить на math.sincos Будет немного быстрее (на сколько - не знаю)
Обсуждают сегодня