PageRenderTime 50ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/Averaging.dpr

https://github.com/whiteTigr/AveragingTest
Pascal | 537 lines | 491 code | 39 blank | 7 comment | 55 complexity | 528f379fcd71b7f5325fd90674faffe2 MD5 | raw file
  1. program Averaging;
  2. {$APPTYPE CONSOLE}
  3. uses
  4. SysUtils, Generics.Collections, Math;
  5. type
  6. TValueList = TList<integer>;
  7. PValueList = ^TValueList;
  8. var
  9. arr: TValueList;
  10. function ReadFile(const fileName: string): TValueList;
  11. var
  12. inputFile: TextFile;
  13. Value: TList<integer>;
  14. int: integer;
  15. test: TValueList;
  16. begin
  17. AssignFile(inputFile, fileName);
  18. Reset(inputFile);
  19. try
  20. Result := TValueList.Create;
  21. Value := TList<integer>.Create;
  22. Result.Clear;
  23. while not eof(inputFile) do
  24. begin
  25. Value.Clear;
  26. while not eoln(inputFile) do
  27. begin
  28. read(inputFile, int);
  29. Value.Add(int);
  30. end;
  31. readln(inputFile);
  32. if Value.Count > 9 then
  33. Result.Add(Value[9]);
  34. end;
  35. finally
  36. CloseFile(inputFile);
  37. Value.Free;
  38. end;
  39. end;
  40. procedure WriteFile(const fileName: string; const arr: TValueList);
  41. var
  42. outputFile: TextFile;
  43. i: integer;
  44. begin
  45. AssignFile(outputFile, fileName);
  46. Rewrite(outputFile);
  47. try
  48. for i := 0 to arr.Count - 1 do
  49. writeln(outputFile, arr[i]);
  50. finally
  51. CloseFile(outputFile);
  52. end;
  53. end;
  54. function NextPoint(index: integer): integer;
  55. var
  56. baiessArr: array[-65536..65536] of integer;
  57. i, j: integer;
  58. begin
  59. for i := -65536 to 65535 do
  60. baiessArr[i] := 0;
  61. for j := index-7 to index do
  62. for i := -500 to 500 do
  63. inc(baiessArr[arr[j] + i], 500 - abs(i));
  64. Result := -65536;
  65. for i := -65535 to 65535 do
  66. if baiessArr[i] > baiessArr[Result] then
  67. Result := i;
  68. Result := baiessArr[Result];
  69. end;
  70. procedure WriteTestFile(const fileName: string);
  71. var
  72. outputFile: TextFile;
  73. i: integer;
  74. begin
  75. AssignFile(outputFile, fileName);
  76. Rewrite(outputFile);
  77. try
  78. for i := 7 to arr.Count - 1 do
  79. writeln(outputFile, arr[i], #9, NextPoint(i));
  80. finally
  81. CloseFile(outputFile);
  82. end;
  83. end;
  84. function shra(value: integer; shiftCount: integer): integer;
  85. const
  86. shiftMask: array[0..31] of cardinal =
  87. ($00000000,
  88. $80000000, $C0000000, $E0000000, $F0000000,
  89. $F8000000, $FC000000, $FE000000, $FF000000,
  90. $FF800000, $FFC00000, $FFE00000, $FFF00000,
  91. $FFF80000, $FFFC0000, $FFFE0000, $FFFF0000,
  92. $FFFF8000, $FFFFC000, $FFFFE000, $FFFFF000,
  93. $FFFFF800, $FFFFFC00, $FFFFFE00, $FFFFFF00,
  94. $FFFFFF80, $FFFFFFC0, $FFFFFFE0, $FFFFFFF0,
  95. $FFFFFFF8, $FFFFFFFC, $FFFFFFFE);
  96. begin
  97. Result := value shr shiftCount;
  98. {$WARNINGS OFF}
  99. if (value and $80000000) <> 0 then
  100. Result := Result or shiftMask[shiftCount and 31];
  101. {$WARNINGS ON}
  102. end;
  103. procedure CalcAtanTable;
  104. var
  105. atg: array[0..31] of real;
  106. i: integer;
  107. begin
  108. for i := 0 to 31 do
  109. atg[i] := System.ArcTan(1/Power(2, i)) * 180 / Pi * 1000000;
  110. end;
  111. procedure SinCos(const angle: integer; out cos: integer; out sin: integer);
  112. const
  113. atg: array[0..26] of integer = (
  114. 45000000 , 26565051 , 14036243 , 7125016 , 3576334 , 1789911 , 895174 , 447614 ,
  115. 223811 , 111906 , 55953 , 27976 , 13988 , 6994 , 3497 , 1749 ,
  116. 874 , 437 , 219 , 109 , 55 , 27 , 14 , 7, 3, 2, 1);
  117. var
  118. i: integer;
  119. x, y, z: integer;
  120. newX, newY: integer;
  121. xHalf, yHalf: integer;
  122. power: integer;
  123. begin
  124. z := angle;
  125. // x := 900502 shl 10; // 900517
  126. x := 922113738;
  127. y := 0;
  128. for i := 1 to 26 do
  129. begin
  130. if z > 0 then
  131. begin
  132. z := z - atg[i];
  133. newX := x - shra(y, i);
  134. newY := y + shra(x, i);
  135. end
  136. else
  137. begin
  138. z := z + atg[i];
  139. newX := x + shra(y, i);
  140. newY := y - shra(x, i);
  141. end;
  142. x := newX;
  143. y := newY;
  144. end;
  145. x := shra(x, 10);
  146. y := shra(y, 10);
  147. cos := round(x);
  148. sin := round(y);
  149. end;
  150. function Sin(angle: integer): integer;
  151. var
  152. intCos, intSin: integer;
  153. sign: integer;
  154. begin
  155. if angle < 0 then
  156. sign := -1
  157. else
  158. sign := 1;
  159. angle := abs(angle);
  160. if angle < 45000000 then
  161. begin
  162. SinCos(angle, intCos, intSin);
  163. Exit(intSin * sign);
  164. end;
  165. if angle < 90000000 then
  166. begin
  167. SinCos(90000000 - angle, intCos, intSin);
  168. Exit(intCos * sign);
  169. end;
  170. if angle < 135000000 then
  171. begin
  172. SinCos(angle - 90000000, intCos, intSin);
  173. Exit(intCos * sign);
  174. end;
  175. SinCos(180000000 - angle, intCos, intSin);
  176. Exit(intSin * sign);
  177. end;
  178. function Cos(angle: integer): integer;
  179. var
  180. intCos, intSin: integer;
  181. begin
  182. angle := abs(angle);
  183. if angle < 45000000 then
  184. begin
  185. SinCos(angle, intCos, intSin);
  186. Exit(intCos);
  187. end;
  188. if angle < 90000000 then
  189. begin
  190. SinCos(90000000 - angle, intCos, intSin);
  191. Exit(intSin);
  192. end;
  193. if angle < 135000000 then
  194. begin
  195. SinCos(angle - 90000000, intCos, intSin);
  196. Exit(-intSin);
  197. end;
  198. SinCos(180000000 - angle, intCos, intSin);
  199. Exit(-intCos);
  200. end;
  201. function Mul(a, b: integer): integer;
  202. begin
  203. Result := shra(shra(a, 5) * shra(b, 5), 10);
  204. end;
  205. function Sqrt(value: integer): integer;
  206. var
  207. mask: integer;
  208. begin
  209. mask := $100000;
  210. Result := 0;
  211. while mask <> 0 do
  212. begin
  213. if Mul(Result, Result) < value then
  214. Result := Result or mask;
  215. if Mul(Result, Result) > value then
  216. Result := Result and not mask;
  217. mask := mask shr 1;
  218. end;
  219. end;
  220. function CosWithSin(angle: integer): integer;
  221. var
  222. sinValue: integer;
  223. begin
  224. sinValue := Sin(angle);
  225. Result := Sqrt((1 shl 20) - Mul(sinValue, sinValue));
  226. if angle > 90000000 then
  227. Result := -Result;
  228. end;
  229. function ACos(value: integer): integer;
  230. const
  231. AngleTable: array[0..26] of integer = (
  232. 45000000 , 22500000 , 11250000 , 5625000 , 2812500 , 1406250 , 703125 , 351562 , 175781 , 87890 ,
  233. 43945 , 21973 , 10986 , 5493 , 2746 , 1373 , 686 , 343 , 172 , 86 , 43 , 22 , 11 , 5, 3, 2, 1);
  234. var
  235. i: integer;
  236. begin
  237. Result := 45000000;
  238. for i := 1 to 26 do
  239. begin
  240. if value <= cos(result) then
  241. result := result + AngleTable[i]
  242. else
  243. result := result - AngleTable[i];
  244. end;
  245. end;
  246. function ASin(value: integer): integer;
  247. const
  248. AngleTable: array[0..26] of integer = (
  249. 45000000 , 22500000 , 11250000 , 5625000 , 2812500 , 1406250 , 703125 , 351562 , 175781 , 87890 ,
  250. 43945 , 21973 , 10986 , 5493 , 2746 , 1373 , 686 , 343 , 172 , 86 , 43 , 22 , 11 , 5, 3, 2, 1);
  251. var
  252. i: integer;
  253. begin
  254. Result := 45000000;
  255. for i := 1 to 26 do
  256. begin
  257. if value <= sin(result) then
  258. result := result + AngleTable[i]
  259. else
  260. result := result - AngleTable[i];
  261. end;
  262. end;
  263. function Distance(lat1, lat2, lon1, lon2: integer): integer;
  264. var
  265. d: integer;
  266. cos_d: integer;
  267. sin_d: integer;
  268. pretc: integer;
  269. tc: integer;
  270. begin
  271. cos_d := Mul(sin(lat1), sin(lat2)) + Mul(Mul(cos(lat1), cos(lat2)), cos(lon1 - lon2));
  272. sin_d := Sqrt(1048576 - Mul(cos_d, cos_d));
  273. d := acos(d);
  274. pretc := round((sin(lat2) - sin(lat1) * cos_d)/(sin_d * cos(lat1)));
  275. tc := 2 * asin(sqrt((1048576 - pretc) div 2));
  276. if sin(lon1 - lon2) < 0 then
  277. Result := tc
  278. else
  279. Result := 360000000 - tc;
  280. end;
  281. function DistanceEtalon(_lat1, _lat2, _lon1, _lon2: integer): integer;
  282. var
  283. d, tc: real;
  284. lat1, lat2, lon1, lon2: real;
  285. begin
  286. lat1 := DegToRad(_lat1 / 1000000);
  287. lat2 := DegToRad(_lat2 / 1000000);
  288. lon1 := DegToRad(_lon1 / 1000000);
  289. lon2 := DegToRad(_lon2 / 1000000);
  290. d := Math.arccos(System.sin(lat1) * System.sin(lat2) + System.cos(lat1) * System.cos(lat2) * System.cos(lon1-lon2));
  291. tc := Math.arccos((System.sin(lat2) - System.sin(lat1) * System.cos(d))/(System.sin(d) * System.cos(lat1)));
  292. if System.sin(lon1-lon2) < 0 then
  293. Result := round(tc)
  294. else
  295. tc := 2 * pi - round(tc);
  296. end;
  297. procedure SinCosTest;
  298. var
  299. i: integer;
  300. intCos, intSin: integer;
  301. realCos, realSin: real;
  302. f: TextFile;
  303. begin
  304. AssignFile(f, 'tmp.txt');
  305. Rewrite(f);
  306. for i := 1 to 45000000 do
  307. begin
  308. SinCos(i, intCos, intSin);
  309. realCos := round(System.Cos(i*Pi/180/1E6)*1024*1024);
  310. realSin := round(System.Sin(i*Pi/180/1E6)*1024*1024);
  311. if (abs(realCos - intCos) > 31) or (abs(realSin - intSin) > 31) then
  312. writeln(f, i, #9, trunc(realCos - intCos), #9, trunc(realSin - intSin));
  313. end;
  314. CloseFile(f);
  315. end;
  316. procedure CosTest;
  317. var
  318. i, j: integer;
  319. intCos, intSin: integer;
  320. realCos, realSin: real;
  321. f: TextFile;
  322. errF: TextFile;
  323. error: integer;
  324. errors: array[-32..32] of integer;
  325. allErrors: array[-32..32] of integer;
  326. begin
  327. AssignFile(f, 'tmp.txt');
  328. Rewrite(f);
  329. AssignFile(errF, 'err.txt');
  330. Rewrite(errF);
  331. for j := -32 to 32 do
  332. begin
  333. errors[j] := 0;
  334. allErrors[j] := 0;
  335. end;
  336. for i := 80000000 to 180000000 do
  337. begin
  338. if i mod 1000000 = 0 then
  339. begin
  340. writeln(f);
  341. writeln(' errors:');
  342. for j := -32 to 32 do
  343. begin
  344. writeln(' ', j, ': ', format('%d', [errors[j]]));
  345. write(f, format('%.5f%%', [errors[j]/1800000]), #9);
  346. inc(allErrors[j], errors[j]);
  347. errors[j] := 0;
  348. end;
  349. writeln(i);
  350. end;
  351. intCos := CosWithSin(i);
  352. realCos := round(System.Cos(i*Pi/180/1E6)*1024*1024);
  353. error := round((realCos - intCos));
  354. if (error > -33) and (error < 32) then
  355. inc(errors[error])
  356. else
  357. inc(errors[32]);
  358. if abs(error) > 15 then
  359. writeln(errf, 'i = ', i, ' err = ', error);
  360. end;
  361. writeln(' All errors:');
  362. for j := -32 to 32 do
  363. begin
  364. writeln(' ', j, ': ', format('%d', [allErrors[j]]));
  365. end;
  366. CloseFile(f);
  367. CloseFIle(errF);
  368. writeln('completed');
  369. end;
  370. procedure ACosTest;
  371. var
  372. i, j: integer;
  373. intValue: integer;
  374. realValue: real;
  375. f: TextFile;
  376. errF: TextFile;
  377. error: integer;
  378. errors: array[-32..32] of integer;
  379. allErrors: array[-32..32] of integer;
  380. begin
  381. AssignFile(f, 'tmp.txt');
  382. Rewrite(f);
  383. AssignFile(errF, 'err.txt');
  384. Rewrite(errF);
  385. for j := -32 to 32 do
  386. begin
  387. errors[j] := 0;
  388. allErrors[j] := 0;
  389. end;
  390. for i := 0 to 1024*1024 do
  391. begin
  392. if i mod 5825 = 0 then
  393. begin
  394. writeln(' errors:');
  395. for j := -32 to 32 do
  396. begin
  397. writeln(' ', j, ': ', format('%d', [errors[j]]));
  398. write(f, format('%.5f%%', [errors[j]/58.25]), #9);
  399. inc(allErrors[j], errors[j]);
  400. errors[j] := 0;
  401. end;
  402. writeln(f);
  403. writeln(i);
  404. end;
  405. intValue := ACos(i);
  406. realValue := round(Math.ArcCos(i/1024/1024)*180/Pi*1E6);
  407. error := round((realValue - intValue));
  408. if (error > -33) and (error < 32) then
  409. inc(errors[error])
  410. else
  411. inc(errors[32]);
  412. if abs(error) > 8 then
  413. writeln(errf, 'i = ', i, ' err = ', error);
  414. end;
  415. writeln(' All errors:');
  416. for j := -32 to 32 do
  417. begin
  418. writeln(' ', j, ': ', format('%d', [allErrors[j]]));
  419. end;
  420. CloseFile(f);
  421. CloseFile(errF);
  422. writeln('completed');
  423. end;
  424. procedure DistanceTest;
  425. var
  426. i, j: integer;
  427. intValue: integer;
  428. realValue: real;
  429. f: TextFile;
  430. errF: TextFile;
  431. error: integer;
  432. errors: array[-32..32] of integer;
  433. allErrors: array[-32..32] of integer;
  434. begin
  435. AssignFile(f, 'tmp.txt');
  436. Rewrite(f);
  437. AssignFile(errF, 'err.txt');
  438. Rewrite(errF);
  439. for j := -32 to 32 do
  440. begin
  441. errors[j] := 0;
  442. allErrors[j] := 0;
  443. end;
  444. for i := 38000000 to 42000000 do
  445. begin
  446. if i mod 100000 = 0 then
  447. begin
  448. writeln(' errors:');
  449. write(f, i, #9);
  450. for j := -32 to 32 do
  451. begin
  452. writeln(' ', j, ': ', format('%d', [errors[j]]));
  453. write(f, format('%.5f%%', [errors[j]/58.25]), #9);
  454. inc(allErrors[j], errors[j]);
  455. errors[j] := 0;
  456. end;
  457. writeln(f);
  458. writeln(i);
  459. end;
  460. if i <> 40000000 then
  461. begin
  462. intValue := Distance(40000000, 40000000, 40000000, i);
  463. realValue := DistanceEtalon(40000000, 40000000, 40000000, i);
  464. end;
  465. error := round((realValue - intValue));
  466. if (error > -33) and (error < 32) then
  467. inc(errors[error])
  468. else
  469. inc(errors[32]);
  470. if abs(error) > 8 then
  471. writeln(errf, 'i = ', i, ' err = ', error);
  472. end;
  473. writeln(' All errors:');
  474. for j := -32 to 32 do
  475. begin
  476. writeln(' ', j, ': ', format('%d', [allErrors[j]]));
  477. end;
  478. CloseFile(f);
  479. CloseFile(errF);
  480. writeln('completed');
  481. end;
  482. var
  483. z: real;
  484. begin
  485. try
  486. // arr := ReadFile('output.txt');
  487. // WriteTestFile('testOut.txt');
  488. // CalcAtanTable;
  489. DistanceTest;
  490. readln;
  491. except
  492. on E: Exception do
  493. begin
  494. Writeln(E.ClassName, ': ', E.Message);
  495. readln;
  496. end;
  497. end;
  498. end.