c_qd.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. /*
  2. * src/c_qd.cc
  3. *
  4. * This work was supported by the Director, Office of Science, Division
  5. * of Mathematical, Information, and Computational Sciences of the
  6. * U.S. Department of Energy under contract number DE-AC03-76SF00098.
  7. *
  8. * Copyright (c) 2000-2001
  9. *
  10. * Contains C wrapper function for quad-double precision arithmetic.
  11. * This can be used from fortran code.
  12. */
  13. #include <cstring>
  14. #include "config.h"
  15. #include <qd/qd_real.h>
  16. #include <qd/c_qd.h>
  17. #define TO_DOUBLE_PTR(a, ptr) ptr[0] = a.x[0]; ptr[1] = a.x[1]; \
  18. ptr[2] = a.x[2]; ptr[3] = a.x[3];
  19. extern "C" {
  20. /* add */
  21. void c_qd_add(const double *a, const double *b, double *c) {
  22. qd_real cc;
  23. cc = qd_real(a) + qd_real(b);
  24. TO_DOUBLE_PTR(cc, c);
  25. }
  26. void c_qd_add_qd_dd(const double *a, const double *b, double *c) {
  27. qd_real cc;
  28. cc = qd_real(a) + dd_real(b);
  29. TO_DOUBLE_PTR(cc, c);
  30. }
  31. void c_qd_add_dd_qd(const double *a, const double *b, double *c) {
  32. qd_real cc;
  33. cc = dd_real(a) + qd_real(b);
  34. TO_DOUBLE_PTR(cc, c);
  35. }
  36. void c_qd_add_qd_d(const double *a, double b, double *c) {
  37. qd_real cc;
  38. cc = qd_real(a) + b;
  39. TO_DOUBLE_PTR(cc, c);
  40. }
  41. void c_qd_add_d_qd(double a, const double *b, double *c) {
  42. qd_real cc;
  43. cc = a + qd_real(b);
  44. TO_DOUBLE_PTR(cc, c);
  45. }
  46. /* sub */
  47. void c_qd_sub(const double *a, const double *b, double *c) {
  48. qd_real cc;
  49. cc = qd_real(a) - qd_real(b);
  50. TO_DOUBLE_PTR(cc, c);
  51. }
  52. void c_qd_sub_qd_dd(const double *a, const double *b, double *c) {
  53. qd_real cc;
  54. cc = qd_real(a) - dd_real(b);
  55. TO_DOUBLE_PTR(cc, c);
  56. }
  57. void c_qd_sub_dd_qd(const double *a, const double *b, double *c) {
  58. qd_real cc;
  59. cc = dd_real(a) - qd_real(b);
  60. TO_DOUBLE_PTR(cc, c);
  61. }
  62. void c_qd_sub_qd_d(const double *a, double b, double *c) {
  63. qd_real cc;
  64. cc = qd_real(a) - b;
  65. TO_DOUBLE_PTR(cc, c);
  66. }
  67. void c_qd_sub_d_qd(double a, const double *b, double *c) {
  68. qd_real cc;
  69. cc = a - qd_real(b);
  70. TO_DOUBLE_PTR(cc, c);
  71. }
  72. /* mul */
  73. void c_qd_mul(const double *a, const double *b, double *c) {
  74. qd_real cc;
  75. cc = qd_real(a) * qd_real(b);
  76. TO_DOUBLE_PTR(cc, c);
  77. }
  78. void c_qd_mul_qd_dd(const double *a, const double *b, double *c) {
  79. qd_real cc;
  80. cc = qd_real(a) * dd_real(b);
  81. TO_DOUBLE_PTR(cc, c);
  82. }
  83. void c_qd_mul_dd_qd(const double *a, const double *b, double *c) {
  84. qd_real cc;
  85. cc = dd_real(a) * qd_real(b);
  86. TO_DOUBLE_PTR(cc, c);
  87. }
  88. void c_qd_mul_qd_d(const double *a, double b, double *c) {
  89. qd_real cc;
  90. cc = qd_real(a) * b;
  91. TO_DOUBLE_PTR(cc, c);
  92. }
  93. void c_qd_mul_d_qd(double a, const double *b, double *c) {
  94. qd_real cc;
  95. cc = a * qd_real(b);
  96. TO_DOUBLE_PTR(cc, c);
  97. }
  98. /* div */
  99. void c_qd_div(const double *a, const double *b, double *c) {
  100. qd_real cc;
  101. cc = qd_real(a) / qd_real(b);
  102. TO_DOUBLE_PTR(cc, c);
  103. }
  104. void c_qd_div_qd_dd(const double *a, const double *b, double *c) {
  105. qd_real cc;
  106. cc = qd_real(a) / dd_real(b);
  107. TO_DOUBLE_PTR(cc, c);
  108. }
  109. void c_qd_div_dd_qd(const double *a, const double *b, double *c) {
  110. qd_real cc;
  111. cc = dd_real(a) / qd_real(b);
  112. TO_DOUBLE_PTR(cc, c);
  113. }
  114. void c_qd_div_qd_d(const double *a, double b, double *c) {
  115. qd_real cc;
  116. cc = qd_real(a) / b;
  117. TO_DOUBLE_PTR(cc, c);
  118. }
  119. void c_qd_div_d_qd(double a, const double *b, double *c) {
  120. qd_real cc;
  121. cc = a / qd_real(b);
  122. TO_DOUBLE_PTR(cc, c);
  123. }
  124. /* selfadd */
  125. void c_qd_selfadd(const double *a, double *b) {
  126. qd_real bb(b);
  127. bb += qd_real(a);
  128. TO_DOUBLE_PTR(bb, b);
  129. }
  130. void c_qd_selfadd_dd(const double *a, double *b) {
  131. qd_real bb(b);
  132. bb += dd_real(a);
  133. TO_DOUBLE_PTR(bb, b);
  134. }
  135. void c_qd_selfadd_d(double a, double *b) {
  136. qd_real bb(b);
  137. bb += a;
  138. TO_DOUBLE_PTR(bb, b);
  139. }
  140. /* selfsub */
  141. void c_qd_selfsub(const double *a, double *b) {
  142. qd_real bb(b);
  143. bb -= qd_real(a);
  144. TO_DOUBLE_PTR(bb, b);
  145. }
  146. void c_qd_selfsub_dd(const double *a, double *b) {
  147. qd_real bb(b);
  148. bb -= dd_real(a);
  149. TO_DOUBLE_PTR(bb, b);
  150. }
  151. void c_qd_selfsub_d(double a, double *b) {
  152. qd_real bb(b);
  153. bb -= a;
  154. TO_DOUBLE_PTR(bb, b);
  155. }
  156. /* selfmul */
  157. void c_qd_selfmul(const double *a, double *b) {
  158. qd_real bb(b);
  159. bb *= qd_real(a);
  160. TO_DOUBLE_PTR(bb, b);
  161. }
  162. void c_qd_selfmul_dd(const double *a, double *b) {
  163. qd_real bb(b);
  164. bb *= dd_real(a);
  165. TO_DOUBLE_PTR(bb, b);
  166. }
  167. void c_qd_selfmul_d(double a, double *b) {
  168. qd_real bb(b);
  169. bb *= a;
  170. TO_DOUBLE_PTR(bb, b);
  171. }
  172. /* selfdiv */
  173. void c_qd_selfdiv(const double *a, double *b) {
  174. qd_real bb(b);
  175. bb /= qd_real(a);
  176. TO_DOUBLE_PTR(bb, b);
  177. }
  178. void c_qd_selfdiv_dd(const double *a, double *b) {
  179. qd_real bb(b);
  180. bb /= dd_real(a);
  181. TO_DOUBLE_PTR(bb, b);
  182. }
  183. void c_qd_selfdiv_d(double a, double *b) {
  184. qd_real bb(b);
  185. bb /= a;
  186. TO_DOUBLE_PTR(bb, b);
  187. }
  188. /* copy */
  189. void c_qd_copy(const double *a, double *b) {
  190. b[0] = a[0];
  191. b[1] = a[1];
  192. b[2] = a[2];
  193. b[3] = a[3];
  194. }
  195. void c_qd_copy_dd(const double *a, double *b) {
  196. b[0] = a[0];
  197. b[1] = a[1];
  198. b[2] = 0.0;
  199. b[3] = 0.0;
  200. }
  201. void c_qd_copy_d(double a, double *b) {
  202. b[0] = a;
  203. b[1] = 0.0;
  204. b[2] = 0.0;
  205. b[3] = 0.0;
  206. }
  207. void c_qd_sqrt(const double *a, double *b) {
  208. qd_real bb;
  209. bb = sqrt(qd_real(a));
  210. TO_DOUBLE_PTR(bb, b);
  211. }
  212. void c_qd_sqr(const double *a, double *b) {
  213. qd_real bb;
  214. bb = sqr(qd_real(a));
  215. TO_DOUBLE_PTR(bb, b);
  216. }
  217. void c_qd_abs(const double *a, double *b) {
  218. qd_real bb;
  219. bb = abs(qd_real(a));
  220. TO_DOUBLE_PTR(bb, b);
  221. }
  222. void c_qd_npwr(const double *a, int n, double *b) {
  223. qd_real bb;
  224. bb = npwr(qd_real(a), n);
  225. TO_DOUBLE_PTR(bb, b);
  226. }
  227. void c_qd_nroot(const double *a, int n, double *b) {
  228. qd_real bb;
  229. bb = nroot(qd_real(a), n);
  230. TO_DOUBLE_PTR(bb, b);
  231. }
  232. void c_qd_nint(const double *a, double *b) {
  233. qd_real bb;
  234. bb = nint(qd_real(a));
  235. TO_DOUBLE_PTR(bb, b);
  236. }
  237. void c_qd_aint(const double *a, double *b) {
  238. qd_real bb;
  239. bb = aint(qd_real(a));
  240. TO_DOUBLE_PTR(bb, b);
  241. }
  242. void c_qd_floor(const double *a, double *b) {
  243. qd_real bb;
  244. bb = floor(qd_real(a));
  245. TO_DOUBLE_PTR(bb, b);
  246. }
  247. void c_qd_ceil(const double *a, double *b) {
  248. qd_real bb;
  249. bb = ceil(qd_real(a));
  250. TO_DOUBLE_PTR(bb, b);
  251. }
  252. void c_qd_log(const double *a, double *b) {
  253. qd_real bb;
  254. bb = log(qd_real(a));
  255. TO_DOUBLE_PTR(bb, b);
  256. }
  257. void c_qd_log10(const double *a, double *b) {
  258. qd_real bb;
  259. bb = log10(qd_real(a));
  260. TO_DOUBLE_PTR(bb, b);
  261. }
  262. void c_qd_exp(const double *a, double *b) {
  263. qd_real bb;
  264. bb = exp(qd_real(a));
  265. TO_DOUBLE_PTR(bb, b);
  266. }
  267. void c_qd_sin(const double *a, double *b) {
  268. qd_real bb;
  269. bb = sin(qd_real(a));
  270. TO_DOUBLE_PTR(bb, b);
  271. }
  272. void c_qd_cos(const double *a, double *b) {
  273. qd_real bb;
  274. bb = cos(qd_real(a));
  275. TO_DOUBLE_PTR(bb, b);
  276. }
  277. void c_qd_tan(const double *a, double *b) {
  278. qd_real bb;
  279. bb = tan(qd_real(a));
  280. TO_DOUBLE_PTR(bb, b);
  281. }
  282. void c_qd_asin(const double *a, double *b) {
  283. qd_real bb;
  284. bb = asin(qd_real(a));
  285. TO_DOUBLE_PTR(bb, b);
  286. }
  287. void c_qd_acos(const double *a, double *b) {
  288. qd_real bb;
  289. bb = acos(qd_real(a));
  290. TO_DOUBLE_PTR(bb, b);
  291. }
  292. void c_qd_atan(const double *a, double *b) {
  293. qd_real bb;
  294. bb = atan(qd_real(a));
  295. TO_DOUBLE_PTR(bb, b);
  296. }
  297. void c_qd_atan2(const double *a, const double *b, double *c) {
  298. qd_real cc;
  299. cc = atan2(qd_real(a), qd_real(b));
  300. TO_DOUBLE_PTR(cc, c);
  301. }
  302. void c_qd_sinh(const double *a, double *b) {
  303. qd_real bb;
  304. bb = sinh(qd_real(a));
  305. TO_DOUBLE_PTR(bb, b);
  306. }
  307. void c_qd_cosh(const double *a, double *b) {
  308. qd_real bb;
  309. bb = cosh(qd_real(a));
  310. TO_DOUBLE_PTR(bb, b);
  311. }
  312. void c_qd_tanh(const double *a, double *b) {
  313. qd_real bb;
  314. bb = tanh(qd_real(a));
  315. TO_DOUBLE_PTR(bb, b);
  316. }
  317. void c_qd_asinh(const double *a, double *b) {
  318. qd_real bb;
  319. bb = asinh(qd_real(a));
  320. TO_DOUBLE_PTR(bb, b);
  321. }
  322. void c_qd_acosh(const double *a, double *b) {
  323. qd_real bb;
  324. bb = acosh(qd_real(a));
  325. TO_DOUBLE_PTR(bb, b);
  326. }
  327. void c_qd_atanh(const double *a, double *b) {
  328. qd_real bb;
  329. bb = atanh(qd_real(a));
  330. TO_DOUBLE_PTR(bb, b);
  331. }
  332. void c_qd_sincos(const double *a, double *s, double *c) {
  333. qd_real ss, cc;
  334. sincos(qd_real(a), ss, cc);
  335. TO_DOUBLE_PTR(cc, c);
  336. TO_DOUBLE_PTR(ss, s);
  337. }
  338. void c_qd_sincosh(const double *a, double *s, double *c) {
  339. qd_real ss, cc;
  340. sincosh(qd_real(a), ss, cc);
  341. TO_DOUBLE_PTR(cc, c);
  342. TO_DOUBLE_PTR(ss, s);
  343. }
  344. void c_qd_read(const char *s, double *a) {
  345. qd_real aa(s);
  346. TO_DOUBLE_PTR(aa, a);
  347. }
  348. void c_qd_swrite(const double *a, int precision, char *s, int len) {
  349. qd_real(a).write(s, len, precision);
  350. }
  351. void c_qd_write(const double *a) {
  352. std::cout << qd_real(a).to_string(qd_real::_ndigits) << std::endl;
  353. }
  354. void c_qd_neg(const double *a, double *b) {
  355. b[0] = -a[0];
  356. b[1] = -a[1];
  357. b[2] = -a[2];
  358. b[3] = -a[3];
  359. }
  360. void c_qd_rand(double *a) {
  361. qd_real aa;
  362. aa = qdrand();
  363. TO_DOUBLE_PTR(aa, a);
  364. }
  365. void c_qd_comp(const double *a, const double *b, int *result) {
  366. qd_real aa(a), bb(b);
  367. if (aa < bb)
  368. *result = -1;
  369. else if (aa > bb)
  370. *result = 1;
  371. else
  372. *result = 0;
  373. }
  374. void c_qd_comp_qd_d(const double *a, double b, int *result) {
  375. qd_real aa(a);
  376. if (aa < b)
  377. *result = -1;
  378. else if (aa > b)
  379. *result = 1;
  380. else
  381. *result = 0;
  382. }
  383. void c_qd_comp_d_qd(double a, const double *b, int *result) {
  384. qd_real bb(b);
  385. if (a < bb)
  386. *result = -1;
  387. else if (a > bb)
  388. *result = 1;
  389. else
  390. *result = 0;
  391. }
  392. void c_qd_pi(double *a) {
  393. TO_DOUBLE_PTR(qd_real::_pi, a);
  394. }
  395. }