Fork of the espurna firmware for `mhsw` switches
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

666 lines
14 KiB

  1. /**
  2. * This code is available at
  3. * http://www.mindspring.com/~pfilandr/C/fs_math/
  4. * and it is believed to be public domain.
  5. */
  6. #ifndef H_FS_MATH_H
  7. #define H_FS_MATH_H
  8. // -----------------------------------------------------------------------------
  9. // fs_math.h
  10. // -----------------------------------------------------------------------------
  11. double fs_sqrt(double x);
  12. double fs_log(double x);
  13. double fs_log10(double x);
  14. /*
  15. ** exp(x) = 1 + x + x^2/2! + x^3/3! + ...
  16. */
  17. double fs_exp(double x);
  18. double fs_modf(double value, double *iptr);
  19. double fs_fmod(double x, double y);
  20. double fs_pow(double x, double y);
  21. double fs_cos(double x);
  22. /*
  23. ** C99
  24. */
  25. double fs_log2(double x);
  26. double fs_exp2(double x);
  27. long double fs_powl(long double x, long double y);
  28. long double fs_sqrtl(long double x);
  29. long double fs_logl(long double x);
  30. long double fs_expl(long double x);
  31. long double fs_cosl(long double x);
  32. long double fs_fmodl(long double x, long double y);
  33. // -----------------------------------------------------------------------------
  34. // fs_math.c
  35. // -----------------------------------------------------------------------------
  36. #include <float.h>
  37. /*
  38. ** pi == (atan(1.0 / 3) + atan(1.0 / 2)) * 4
  39. */
  40. static double fs_pi(void);
  41. static long double fs_pil(void);
  42. double fs_sqrt(double x)
  43. {
  44. int n;
  45. double a, b;
  46. if (x > 0 && DBL_MAX >= x) {
  47. for (n = 0; x > 2; x /= 4) {
  48. ++n;
  49. }
  50. while (0.5 > x) {
  51. --n;
  52. x *= 4;
  53. }
  54. a = x;
  55. b = (1 + x) / 2;
  56. do {
  57. x = b;
  58. b = (a / x + x) / 2;
  59. } while (x > b);
  60. while (n > 0) {
  61. x *= 2;
  62. --n;
  63. }
  64. while (0 > n) {
  65. x /= 2;
  66. ++n;
  67. }
  68. } else {
  69. if (x != 0) {
  70. x = DBL_MAX;
  71. }
  72. }
  73. return x;
  74. }
  75. double fs_log(double x)
  76. {
  77. int n;
  78. double a, b, c, epsilon;
  79. static double A, B, C;
  80. static int initialized;
  81. if (x > 0 && DBL_MAX >= x) {
  82. if (!initialized) {
  83. initialized = 1;
  84. A = fs_sqrt(2);
  85. B = A / 2;
  86. C = fs_log(A);
  87. }
  88. for (n = 0; x > A; x /= 2) {
  89. ++n;
  90. }
  91. while (B > x) {
  92. --n;
  93. x *= 2;
  94. }
  95. a = (x - 1) / (x + 1);
  96. x = C * n + a;
  97. c = a * a;
  98. n = 1;
  99. epsilon = DBL_EPSILON * x;
  100. if (0 > a) {
  101. if (epsilon > 0) {
  102. epsilon = -epsilon;
  103. }
  104. do {
  105. n += 2;
  106. a *= c;
  107. b = a / n;
  108. x += b;
  109. } while (epsilon > b);
  110. } else {
  111. if (0 > epsilon) {
  112. epsilon = -epsilon;
  113. }
  114. do {
  115. n += 2;
  116. a *= c;
  117. b = a / n;
  118. x += b;
  119. } while (b > epsilon);
  120. }
  121. x *= 2;
  122. } else {
  123. x = -DBL_MAX;
  124. }
  125. return x;
  126. }
  127. double fs_log10(double x)
  128. {
  129. static double log_10;
  130. static int initialized;
  131. if (!initialized) {
  132. initialized = 1;
  133. log_10 = fs_log(10);
  134. }
  135. return x > 0 && DBL_MAX >= x ? fs_log(x) / log_10 : fs_log(x);
  136. }
  137. double fs_exp(double x)
  138. {
  139. unsigned n, square;
  140. double b, e;
  141. static double x_max, x_min, epsilon;
  142. static int initialized;
  143. if (!initialized) {
  144. initialized = 1;
  145. x_max = fs_log(DBL_MAX);
  146. x_min = fs_log(DBL_MIN);
  147. epsilon = DBL_EPSILON / 4;
  148. }
  149. if (x_max >= x && x >= x_min) {
  150. for (square = 0; x > 1; x /= 2) {
  151. ++square;
  152. }
  153. while (-1 > x) {
  154. ++square;
  155. x /= 2;
  156. }
  157. e = b = n = 1;
  158. do {
  159. b /= n++;
  160. b *= x;
  161. e += b;
  162. b /= n++;
  163. b *= x;
  164. e += b;
  165. } while (b > epsilon);
  166. while (square-- != 0) {
  167. e *= e;
  168. }
  169. } else {
  170. e = x > 0 ? DBL_MAX : 0;
  171. }
  172. return e;
  173. }
  174. double fs_modf(double value, double *iptr)
  175. {
  176. double a, b;
  177. const double c = value;
  178. if (0 > c) {
  179. value = -value;
  180. }
  181. if (DBL_MAX >= value) {
  182. for (*iptr = 0; value >= 1; value -= b) {
  183. a = value / 2;
  184. b = 1;
  185. while (a >= b) {
  186. b *= 2;
  187. }
  188. *iptr += b;
  189. }
  190. } else {
  191. *iptr = value;
  192. value = 0;
  193. }
  194. if (0 > c) {
  195. *iptr = -*iptr;
  196. value = -value;
  197. }
  198. return value;
  199. }
  200. double fs_fmod(double x, double y)
  201. {
  202. double a, b;
  203. const double c = x;
  204. if (0 > c) {
  205. x = -x;
  206. }
  207. if (0 > y) {
  208. y = -y;
  209. }
  210. if (y != 0 && DBL_MAX >= y && DBL_MAX >= x) {
  211. while (x >= y) {
  212. a = x / 2;
  213. b = y;
  214. while (a >= b) {
  215. b *= 2;
  216. }
  217. x -= b;
  218. }
  219. } else {
  220. x = 0;
  221. }
  222. return 0 > c ? -x : x;
  223. }
  224. double fs_pow(double x, double y)
  225. {
  226. double p = 0;
  227. if (0 > x && fs_fmod(y, 1) == 0) {
  228. if (fs_fmod(y, 2) == 0) {
  229. p = fs_exp(fs_log(-x) * y);
  230. } else {
  231. p = -fs_exp(fs_log(-x) * y);
  232. }
  233. } else {
  234. if (x != 0 || 0 >= y) {
  235. p = fs_exp(fs_log( x) * y);
  236. }
  237. }
  238. return p;
  239. }
  240. static double fs_pi(void)
  241. {
  242. unsigned n;
  243. double a, b, epsilon;
  244. static double p;
  245. static int initialized;
  246. if (!initialized) {
  247. initialized = 1;
  248. epsilon = DBL_EPSILON / 4;
  249. n = 1;
  250. a = 3;
  251. do {
  252. a /= 9;
  253. b = a / n;
  254. n += 2;
  255. a /= 9;
  256. b -= a / n;
  257. n += 2;
  258. p += b;
  259. } while (b > epsilon);
  260. epsilon = DBL_EPSILON / 2;
  261. n = 1;
  262. a = 2;
  263. do {
  264. a /= 4;
  265. b = a / n;
  266. n += 2;
  267. a /= 4;
  268. b -= a / n;
  269. n += 2;
  270. p += b;
  271. } while (b > epsilon);
  272. p *= 4;
  273. }
  274. return p;
  275. }
  276. double fs_cos(double x)
  277. {
  278. unsigned n;
  279. int negative, sine;
  280. double a, b, c;
  281. static double pi, two_pi, half_pi, third_pi, epsilon;
  282. static int initialized;
  283. if (0 > x) {
  284. x = -x;
  285. }
  286. if (DBL_MAX >= x) {
  287. if (!initialized) {
  288. initialized = 1;
  289. pi = fs_pi();
  290. two_pi = 2 * pi;
  291. half_pi = pi / 2;
  292. third_pi = pi / 3;
  293. epsilon = DBL_EPSILON / 2;
  294. }
  295. if (x > two_pi) {
  296. x = fs_fmod(x, two_pi);
  297. }
  298. if (x > pi) {
  299. x = two_pi - x;
  300. }
  301. if (x > half_pi) {
  302. x = pi - x;
  303. negative = 1;
  304. } else {
  305. negative = 0;
  306. }
  307. if (x > third_pi) {
  308. x = half_pi - x;
  309. sine = 1;
  310. } else {
  311. sine = 0;
  312. }
  313. c = x * x;
  314. x = n = 0;
  315. a = 1;
  316. do {
  317. b = a;
  318. a *= c;
  319. a /= ++n;
  320. a /= ++n;
  321. b -= a;
  322. a *= c;
  323. a /= ++n;
  324. a /= ++n;
  325. x += b;
  326. } while (b > epsilon);
  327. if (sine) {
  328. x = fs_sqrt((1 - x) * (1 + x));
  329. }
  330. if (negative) {
  331. x = -x;
  332. }
  333. } else {
  334. x = -DBL_MAX;
  335. }
  336. return x;
  337. }
  338. double fs_log2(double x)
  339. {
  340. static double log_2;
  341. static int initialized;
  342. if (!initialized) {
  343. initialized = 1;
  344. log_2 = fs_log(2);
  345. }
  346. return x > 0 && DBL_MAX >= x ? fs_log(x) / log_2 : fs_log(x);
  347. }
  348. double fs_exp2(double x)
  349. {
  350. static double log_2;
  351. static int initialized;
  352. if (!initialized) {
  353. initialized = 1;
  354. log_2 = fs_log(2);
  355. }
  356. return fs_exp(x * log_2);
  357. }
  358. long double fs_powl(long double x, long double y)
  359. {
  360. long double p;
  361. if (0 > x && fs_fmodl(y, 1) == 0) {
  362. if (fs_fmodl(y, 2) == 0) {
  363. p = fs_expl(fs_logl(-x) * y);
  364. } else {
  365. p = -fs_expl(fs_logl(-x) * y);
  366. }
  367. } else {
  368. if (x != 0 || 0 >= y) {
  369. p = fs_expl(fs_logl( x) * y);
  370. } else {
  371. p = 0;
  372. }
  373. }
  374. return p;
  375. }
  376. long double fs_sqrtl(long double x)
  377. {
  378. long int n;
  379. long double a, b;
  380. if (x > 0 && LDBL_MAX >= x) {
  381. for (n = 0; x > 2; x /= 4) {
  382. ++n;
  383. }
  384. while (0.5 > x) {
  385. --n;
  386. x *= 4;
  387. }
  388. a = x;
  389. b = (1 + x) / 2;
  390. do {
  391. x = b;
  392. b = (a / x + x) / 2;
  393. } while (x > b);
  394. while (n > 0) {
  395. x *= 2;
  396. --n;
  397. }
  398. while (0 > n) {
  399. x /= 2;
  400. ++n;
  401. }
  402. } else {
  403. if (x != 0) {
  404. x = LDBL_MAX;
  405. }
  406. }
  407. return x;
  408. }
  409. long double fs_logl(long double x)
  410. {
  411. long int n;
  412. long double a, b, c, epsilon;
  413. static long double A, B, C;
  414. static int initialized;
  415. if (x > 0 && LDBL_MAX >= x) {
  416. if (!initialized) {
  417. initialized = 1;
  418. B = 1.5;
  419. do {
  420. A = B;
  421. B = 1 / A + A / 2;
  422. } while (A > B);
  423. B /= 2;
  424. C = fs_logl(A);
  425. }
  426. for (n = 0; x > A; x /= 2) {
  427. ++n;
  428. }
  429. while (B > x) {
  430. --n;
  431. x *= 2;
  432. }
  433. a = (x - 1) / (x + 1);
  434. x = C * n + a;
  435. c = a * a;
  436. n = 1;
  437. epsilon = LDBL_EPSILON * x;
  438. if (0 > a) {
  439. if (epsilon > 0) {
  440. epsilon = -epsilon;
  441. }
  442. do {
  443. n += 2;
  444. a *= c;
  445. b = a / n;
  446. x += b;
  447. } while (epsilon > b);
  448. } else {
  449. if (0 > epsilon) {
  450. epsilon = -epsilon;
  451. }
  452. do {
  453. n += 2;
  454. a *= c;
  455. b = a / n;
  456. x += b;
  457. } while (b > epsilon);
  458. }
  459. x *= 2;
  460. } else {
  461. x = -LDBL_MAX;
  462. }
  463. return x;
  464. }
  465. long double fs_expl(long double x)
  466. {
  467. long unsigned n, square;
  468. long double b, e;
  469. static long double x_max, x_min, epsilon;
  470. static int initialized;
  471. if (!initialized) {
  472. initialized = 1;
  473. x_max = fs_logl(LDBL_MAX);
  474. x_min = fs_logl(LDBL_MIN);
  475. epsilon = LDBL_EPSILON / 4;
  476. }
  477. if (x_max >= x && x >= x_min) {
  478. for (square = 0; x > 1; x /= 2) {
  479. ++square;
  480. }
  481. while (-1 > x) {
  482. ++square;
  483. x /= 2;
  484. }
  485. e = b = n = 1;
  486. do {
  487. b /= n++;
  488. b *= x;
  489. e += b;
  490. b /= n++;
  491. b *= x;
  492. e += b;
  493. } while (b > epsilon);
  494. while (square-- != 0) {
  495. e *= e;
  496. }
  497. } else {
  498. e = x > 0 ? LDBL_MAX : 0;
  499. }
  500. return e;
  501. }
  502. static long double fs_pil(void)
  503. {
  504. long unsigned n;
  505. long double a, b, epsilon;
  506. static long double p;
  507. static int initialized;
  508. if (!initialized) {
  509. initialized = 1;
  510. epsilon = LDBL_EPSILON / 4;
  511. n = 1;
  512. a = 3;
  513. do {
  514. a /= 9;
  515. b = a / n;
  516. n += 2;
  517. a /= 9;
  518. b -= a / n;
  519. n += 2;
  520. p += b;
  521. } while (b > epsilon);
  522. epsilon = LDBL_EPSILON / 2;
  523. n = 1;
  524. a = 2;
  525. do {
  526. a /= 4;
  527. b = a / n;
  528. n += 2;
  529. a /= 4;
  530. b -= a / n;
  531. n += 2;
  532. p += b;
  533. } while (b > epsilon);
  534. p *= 4;
  535. }
  536. return p;
  537. }
  538. long double fs_cosl(long double x)
  539. {
  540. long unsigned n;
  541. int negative, sine;
  542. long double a, b, c;
  543. static long double pi, two_pi, half_pi, third_pi, epsilon;
  544. static int initialized;
  545. if (0 > x) {
  546. x = -x;
  547. }
  548. if (LDBL_MAX >= x) {
  549. if (!initialized) {
  550. initialized = 1;
  551. pi = fs_pil();
  552. two_pi = 2 * pi;
  553. half_pi = pi / 2;
  554. third_pi = pi / 3;
  555. epsilon = LDBL_EPSILON / 2;
  556. }
  557. if (x > two_pi) {
  558. x = fs_fmodl(x, two_pi);
  559. }
  560. if (x > pi) {
  561. x = two_pi - x;
  562. }
  563. if (x > half_pi) {
  564. x = pi - x;
  565. negative = 1;
  566. } else {
  567. negative = 0;
  568. }
  569. if (x > third_pi) {
  570. x = half_pi - x;
  571. sine = 1;
  572. } else {
  573. sine = 0;
  574. }
  575. c = x * x;
  576. x = n = 0;
  577. a = 1;
  578. do {
  579. b = a;
  580. a *= c;
  581. a /= ++n;
  582. a /= ++n;
  583. b -= a;
  584. a *= c;
  585. a /= ++n;
  586. a /= ++n;
  587. x += b;
  588. } while (b > epsilon);
  589. if (sine) {
  590. x = fs_sqrtl((1 - x) * (1 + x));
  591. }
  592. if (negative) {
  593. x = -x;
  594. }
  595. } else {
  596. x = -LDBL_MAX;
  597. }
  598. return x;
  599. }
  600. long double fs_fmodl(long double x, long double y)
  601. {
  602. long double a, b;
  603. const long double c = x;
  604. if (0 > c) {
  605. x = -x;
  606. }
  607. if (0 > y) {
  608. y = -y;
  609. }
  610. if (y != 0 && LDBL_MAX >= y && LDBL_MAX >= x) {
  611. while (x >= y) {
  612. a = x / 2;
  613. b = y;
  614. while (a >= b) {
  615. b *= 2;
  616. }
  617. x -= b;
  618. }
  619. } else {
  620. x = 0;
  621. }
  622. return 0 > c ? -x : x;
  623. }
  624. #endif