File indexing completed on 2026-08-06 09:31:07
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef _QD_QD_INLINE_H
0014 #define _QD_QD_INLINE_H
0015
0016 #include <cmath>
0017 #include <qd/inline.h>
0018
0019 #ifndef QD_INLINE
0020 #define inline
0021 #endif
0022
0023
0024 inline qd_real::qd_real(double x0, double x1, double x2, double x3) {
0025 x[0] = x0;
0026 x[1] = x1;
0027 x[2] = x2;
0028 x[3] = x3;
0029 }
0030
0031 inline qd_real::qd_real(const double *xx) {
0032 x[0] = xx[0];
0033 x[1] = xx[1];
0034 x[2] = xx[2];
0035 x[3] = xx[3];
0036 }
0037
0038 inline qd_real::qd_real(double x0) {
0039 x[0] = x0;
0040 x[1] = x[2] = x[3] = 0.0;
0041 }
0042
0043 inline qd_real::qd_real() {
0044 x[0] = 0.0;
0045 x[1] = 0.0;
0046 x[2] = 0.0;
0047 x[3] = 0.0;
0048 }
0049
0050 inline qd_real::qd_real(const dd_real &a) {
0051 x[0] = a._hi();
0052 x[1] = a._lo();
0053 x[2] = x[3] = 0.0;
0054 }
0055
0056 inline qd_real::qd_real(int i) {
0057 x[0] = static_cast<double>(i);
0058 x[1] = x[2] = x[3] = 0.0;
0059 }
0060
0061
0062 inline double qd_real::operator[](int i) const {
0063 return x[i];
0064 }
0065
0066 inline double &qd_real::operator[](int i) {
0067 return x[i];
0068 }
0069
0070 inline bool qd_real::isnan() const {
0071 return QD_ISNAN(x[0]) || QD_ISNAN(x[1]) || QD_ISNAN(x[2]) || QD_ISNAN(x[3]);
0072 }
0073
0074
0075 namespace qd {
0076 inline void quick_renorm(double &c0, double &c1,
0077 double &c2, double &c3, double &c4) {
0078 double t0, t1, t2, t3;
0079 double s;
0080 s = qd::quick_two_sum(c3, c4, t3);
0081 s = qd::quick_two_sum(c2, s , t2);
0082 s = qd::quick_two_sum(c1, s , t1);
0083 c0 = qd::quick_two_sum(c0, s , t0);
0084
0085 s = qd::quick_two_sum(t2, t3, t2);
0086 s = qd::quick_two_sum(t1, s , t1);
0087 c1 = qd::quick_two_sum(t0, s , t0);
0088
0089 s = qd::quick_two_sum(t1, t2, t1);
0090 c2 = qd::quick_two_sum(t0, s , t0);
0091
0092 c3 = t0 + t1;
0093 }
0094
0095 inline void renorm(double &c0, double &c1,
0096 double &c2, double &c3) {
0097 double s0, s1, s2 = 0.0, s3 = 0.0;
0098
0099 if (QD_ISINF(c0)) return;
0100
0101 s0 = qd::quick_two_sum(c2, c3, c3);
0102 s0 = qd::quick_two_sum(c1, s0, c2);
0103 c0 = qd::quick_two_sum(c0, s0, c1);
0104
0105 s0 = c0;
0106 s1 = c1;
0107 if (s1 != 0.0) {
0108 s1 = qd::quick_two_sum(s1, c2, s2);
0109 if (s2 != 0.0)
0110 s2 = qd::quick_two_sum(s2, c3, s3);
0111 else
0112 s1 = qd::quick_two_sum(s1, c3, s2);
0113 } else {
0114 s0 = qd::quick_two_sum(s0, c2, s1);
0115 if (s1 != 0.0)
0116 s1 = qd::quick_two_sum(s1, c3, s2);
0117 else
0118 s0 = qd::quick_two_sum(s0, c3, s1);
0119 }
0120
0121 c0 = s0;
0122 c1 = s1;
0123 c2 = s2;
0124 c3 = s3;
0125 }
0126
0127 inline void renorm(double &c0, double &c1,
0128 double &c2, double &c3, double &c4) {
0129 double s0, s1, s2 = 0.0, s3 = 0.0;
0130
0131 if (QD_ISINF(c0)) return;
0132
0133 s0 = qd::quick_two_sum(c3, c4, c4);
0134 s0 = qd::quick_two_sum(c2, s0, c3);
0135 s0 = qd::quick_two_sum(c1, s0, c2);
0136 c0 = qd::quick_two_sum(c0, s0, c1);
0137
0138 s0 = c0;
0139 s1 = c1;
0140
0141 if (s1 != 0.0) {
0142 s1 = qd::quick_two_sum(s1, c2, s2);
0143 if (s2 != 0.0) {
0144 s2 = qd::quick_two_sum(s2, c3, s3);
0145 if (s3 != 0.0)
0146 s3 += c4;
0147 else
0148 s2 = qd::quick_two_sum(s2, c4, s3);
0149 } else {
0150 s1 = qd::quick_two_sum(s1, c3, s2);
0151 if (s2 != 0.0)
0152 s2 = qd::quick_two_sum(s2, c4, s3);
0153 else
0154 s1 = qd::quick_two_sum(s1, c4, s2);
0155 }
0156 } else {
0157 s0 = qd::quick_two_sum(s0, c2, s1);
0158 if (s1 != 0.0) {
0159 s1 = qd::quick_two_sum(s1, c3, s2);
0160 if (s2 != 0.0)
0161 s2 = qd::quick_two_sum(s2, c4, s3);
0162 else
0163 s1 = qd::quick_two_sum(s1, c4, s2);
0164 } else {
0165 s0 = qd::quick_two_sum(s0, c3, s1);
0166 if (s1 != 0.0)
0167 s1 = qd::quick_two_sum(s1, c4, s2);
0168 else
0169 s0 = qd::quick_two_sum(s0, c4, s1);
0170 }
0171 }
0172
0173 c0 = s0;
0174 c1 = s1;
0175 c2 = s2;
0176 c3 = s3;
0177 }
0178 }
0179
0180 inline void qd_real::renorm() {
0181 qd::renorm(x[0], x[1], x[2], x[3]);
0182 }
0183
0184 inline void qd_real::renorm(double &e) {
0185 qd::renorm(x[0], x[1], x[2], x[3], e);
0186 }
0187
0188
0189
0190 namespace qd {
0191
0192 inline void three_sum(double &a, double &b, double &c) {
0193 double t1, t2, t3;
0194 t1 = qd::two_sum(a, b, t2);
0195 a = qd::two_sum(c, t1, t3);
0196 b = qd::two_sum(t2, t3, c);
0197 }
0198
0199 inline void three_sum2(double &a, double &b, double &c) {
0200 double t1, t2, t3;
0201 t1 = qd::two_sum(a, b, t2);
0202 a = qd::two_sum(c, t1, t3);
0203 b = t2 + t3;
0204 }
0205
0206 }
0207
0208
0209 inline qd_real operator+(const qd_real &a, double b) {
0210 double c0, c1, c2, c3;
0211 double e;
0212
0213 c0 = qd::two_sum(a[0], b, e);
0214 c1 = qd::two_sum(a[1], e, e);
0215 c2 = qd::two_sum(a[2], e, e);
0216 c3 = qd::two_sum(a[3], e, e);
0217
0218 qd::renorm(c0, c1, c2, c3, e);
0219
0220 return qd_real(c0, c1, c2, c3);
0221 }
0222
0223
0224 inline qd_real operator+(const qd_real &a, const dd_real &b) {
0225
0226 double s0, s1, s2, s3;
0227 double t0, t1;
0228
0229 s0 = qd::two_sum(a[0], b._hi(), t0);
0230 s1 = qd::two_sum(a[1], b._lo(), t1);
0231
0232 s1 = qd::two_sum(s1, t0, t0);
0233
0234 s2 = a[2];
0235 qd::three_sum(s2, t0, t1);
0236
0237 s3 = qd::two_sum(t0, a[3], t0);
0238 t0 += t1;
0239
0240 qd::renorm(s0, s1, s2, s3, t0);
0241 return qd_real(s0, s1, s2, s3);
0242 }
0243
0244
0245
0246 inline qd_real operator+(double a, const qd_real &b) {
0247 return (b + a);
0248 }
0249
0250
0251 inline qd_real operator+(const dd_real &a, const qd_real &b) {
0252 return (b + a);
0253 }
0254
0255 namespace qd {
0256
0257
0258
0259
0260
0261 inline double quick_three_accum(double &a, double &b, double c) {
0262 double s;
0263 bool za, zb;
0264
0265 s = qd::two_sum(b, c, b);
0266 s = qd::two_sum(a, s, a);
0267
0268 za = (a != 0.0);
0269 zb = (b != 0.0);
0270
0271 if (za && zb)
0272 return s;
0273
0274 if (!zb) {
0275 b = a;
0276 a = s;
0277 } else {
0278 a = s;
0279 }
0280
0281 return 0.0;
0282 }
0283
0284 }
0285
0286 inline qd_real qd_real::ieee_add(const qd_real &a, const qd_real &b) {
0287 int i, j, k;
0288 double s, t;
0289 double u, v;
0290 double x[4] = {0.0, 0.0, 0.0, 0.0};
0291
0292 i = j = k = 0;
0293 if (std::abs(a[i]) > std::abs(b[j]))
0294 u = a[i++];
0295 else
0296 u = b[j++];
0297 if (std::abs(a[i]) > std::abs(b[j]))
0298 v = a[i++];
0299 else
0300 v = b[j++];
0301
0302 u = qd::quick_two_sum(u, v, v);
0303
0304 while (k < 4) {
0305 if (i >= 4 && j >= 4) {
0306 x[k] = u;
0307 if (k < 3)
0308 x[++k] = v;
0309 break;
0310 }
0311
0312 if (i >= 4)
0313 t = b[j++];
0314 else if (j >= 4)
0315 t = a[i++];
0316 else if (std::abs(a[i]) > std::abs(b[j])) {
0317 t = a[i++];
0318 } else
0319 t = b[j++];
0320
0321 s = qd::quick_three_accum(u, v, t);
0322
0323 if (s != 0.0) {
0324 x[k++] = s;
0325 }
0326 }
0327
0328
0329 for (k = i; k < 4; k++)
0330 x[3] += a[k];
0331 for (k = j; k < 4; k++)
0332 x[3] += b[k];
0333
0334 qd::renorm(x[0], x[1], x[2], x[3]);
0335 return qd_real(x[0], x[1], x[2], x[3]);
0336 }
0337
0338 inline qd_real qd_real::sloppy_add(const qd_real &a, const qd_real &b) {
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360 double s0, s1, s2, s3;
0361 double t0, t1, t2, t3;
0362
0363 double v0, v1, v2, v3;
0364 double u0, u1, u2, u3;
0365 double w0, w1, w2, w3;
0366
0367 s0 = a[0] + b[0];
0368 s1 = a[1] + b[1];
0369 s2 = a[2] + b[2];
0370 s3 = a[3] + b[3];
0371
0372 v0 = s0 - a[0];
0373 v1 = s1 - a[1];
0374 v2 = s2 - a[2];
0375 v3 = s3 - a[3];
0376
0377 u0 = s0 - v0;
0378 u1 = s1 - v1;
0379 u2 = s2 - v2;
0380 u3 = s3 - v3;
0381
0382 w0 = a[0] - u0;
0383 w1 = a[1] - u1;
0384 w2 = a[2] - u2;
0385 w3 = a[3] - u3;
0386
0387 u0 = b[0] - v0;
0388 u1 = b[1] - v1;
0389 u2 = b[2] - v2;
0390 u3 = b[3] - v3;
0391
0392 t0 = w0 + u0;
0393 t1 = w1 + u1;
0394 t2 = w2 + u2;
0395 t3 = w3 + u3;
0396
0397 s1 = qd::two_sum(s1, t0, t0);
0398 qd::three_sum(s2, t0, t1);
0399 qd::three_sum2(s3, t0, t2);
0400 t0 = t0 + t1 + t3;
0401
0402
0403 qd::renorm(s0, s1, s2, s3, t0);
0404 return qd_real(s0, s1, s2, s3);
0405 }
0406
0407
0408 inline qd_real operator+(const qd_real &a, const qd_real &b) {
0409 #ifndef QD_IEEE_ADD
0410 return qd_real::sloppy_add(a, b);
0411 #else
0412 return qd_real::ieee_add(a, b);
0413 #endif
0414 }
0415
0416
0417
0418
0419
0420 inline qd_real &qd_real::operator+=(double a) {
0421 *this = *this + a;
0422 return *this;
0423 }
0424
0425
0426 inline qd_real &qd_real::operator+=(const dd_real &a) {
0427 *this = *this + a;
0428 return *this;
0429 }
0430
0431
0432 inline qd_real &qd_real::operator+=(const qd_real &a) {
0433 *this = *this + a;
0434 return *this;
0435 }
0436
0437
0438 inline qd_real qd_real::operator-() const {
0439 return qd_real(-x[0], -x[1], -x[2], -x[3]);
0440 }
0441
0442
0443 inline qd_real operator-(const qd_real &a, double b) {
0444 return (a + (-b));
0445 }
0446
0447 inline qd_real operator-(double a, const qd_real &b) {
0448 return (a + (-b));
0449 }
0450
0451 inline qd_real operator-(const qd_real &a, const dd_real &b) {
0452 return (a + (-b));
0453 }
0454
0455 inline qd_real operator-(const dd_real &a, const qd_real &b) {
0456 return (a + (-b));
0457 }
0458
0459 inline qd_real operator-(const qd_real &a, const qd_real &b) {
0460 return (a + (-b));
0461 }
0462
0463
0464 inline qd_real &qd_real::operator-=(double a) {
0465 return ((*this) += (-a));
0466 }
0467
0468 inline qd_real &qd_real::operator-=(const dd_real &a) {
0469 return ((*this) += (-a));
0470 }
0471
0472 inline qd_real &qd_real::operator-=(const qd_real &a) {
0473 return ((*this) += (-a));
0474 }
0475
0476
0477 inline qd_real operator*(double a, const qd_real &b) {
0478 return (b * a);
0479 }
0480
0481 inline qd_real operator*(const dd_real &a, const qd_real &b) {
0482 return (b * a);
0483 }
0484
0485 inline qd_real mul_pwr2(const qd_real &a, double b) {
0486 return qd_real(a[0] * b, a[1] * b, a[2] * b, a[3] * b);
0487 }
0488
0489
0490 inline qd_real operator*(const qd_real &a, double b) {
0491 double p0, p1, p2, p3;
0492 double q0, q1, q2;
0493 double s0, s1, s2, s3, s4;
0494
0495 p0 = qd::two_prod(a[0], b, q0);
0496 p1 = qd::two_prod(a[1], b, q1);
0497 p2 = qd::two_prod(a[2], b, q2);
0498 p3 = a[3] * b;
0499
0500 s0 = p0;
0501
0502 s1 = qd::two_sum(q0, p1, s2);
0503
0504 qd::three_sum(s2, q1, p2);
0505
0506 qd::three_sum2(q1, q2, p3);
0507 s3 = q1;
0508
0509 s4 = q2 + p2;
0510
0511 qd::renorm(s0, s1, s2, s3, s4);
0512 return qd_real(s0, s1, s2, s3);
0513
0514 }
0515
0516
0517
0518
0519
0520
0521
0522
0523
0524
0525 inline qd_real operator*(const qd_real &a, const dd_real &b) {
0526 double p0, p1, p2, p3, p4;
0527 double q0, q1, q2, q3, q4;
0528 double s0, s1, s2;
0529 double t0, t1;
0530
0531 p0 = qd::two_prod(a[0], b._hi(), q0);
0532 p1 = qd::two_prod(a[0], b._lo(), q1);
0533 p2 = qd::two_prod(a[1], b._hi(), q2);
0534 p3 = qd::two_prod(a[1], b._lo(), q3);
0535 p4 = qd::two_prod(a[2], b._hi(), q4);
0536
0537 qd::three_sum(p1, p2, q0);
0538
0539
0540 qd::three_sum(p2, p3, p4);
0541 q1 = qd::two_sum(q1, q2, q2);
0542 s0 = qd::two_sum(p2, q1, t0);
0543 s1 = qd::two_sum(p3, q2, t1);
0544 s1 = qd::two_sum(s1, t0, t0);
0545 s2 = t0 + t1 + p4;
0546 p2 = s0;
0547
0548 p3 = a[2] * b._hi() + a[3] * b._lo() + q3 + q4;
0549 qd::three_sum2(p3, q0, s1);
0550 p4 = q0 + s2;
0551
0552 qd::renorm(p0, p1, p2, p3, p4);
0553 return qd_real(p0, p1, p2, p3);
0554 }
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564
0565
0566
0567 inline qd_real qd_real::sloppy_mul(const qd_real &a, const qd_real &b) {
0568 double p0, p1, p2, p3, p4, p5;
0569 double q0, q1, q2, q3, q4, q5;
0570 double t0, t1;
0571 double s0, s1, s2;
0572
0573 p0 = qd::two_prod(a[0], b[0], q0);
0574
0575 p1 = qd::two_prod(a[0], b[1], q1);
0576 p2 = qd::two_prod(a[1], b[0], q2);
0577
0578 p3 = qd::two_prod(a[0], b[2], q3);
0579 p4 = qd::two_prod(a[1], b[1], q4);
0580 p5 = qd::two_prod(a[2], b[0], q5);
0581
0582
0583 qd::three_sum(p1, p2, q0);
0584
0585
0586 qd::three_sum(p2, q1, q2);
0587 qd::three_sum(p3, p4, p5);
0588
0589 s0 = qd::two_sum(p2, p3, t0);
0590 s1 = qd::two_sum(q1, p4, t1);
0591 s2 = q2 + p5;
0592 s1 = qd::two_sum(s1, t0, t0);
0593 s2 += (t0 + t1);
0594
0595
0596 s1 += a[0]*b[3] + a[1]*b[2] + a[2]*b[1] + a[3]*b[0] + q0 + q3 + q4 + q5;
0597 qd::renorm(p0, p1, s0, s1, s2);
0598 return qd_real(p0, p1, s0, s1);
0599 }
0600
0601 inline qd_real qd_real::accurate_mul(const qd_real &a, const qd_real &b) {
0602 double p0, p1, p2, p3, p4, p5;
0603 double q0, q1, q2, q3, q4, q5;
0604 double p6, p7, p8, p9;
0605 double q6, q7, q8, q9;
0606 double r0, r1;
0607 double t0, t1;
0608 double s0, s1, s2;
0609
0610 p0 = qd::two_prod(a[0], b[0], q0);
0611
0612 p1 = qd::two_prod(a[0], b[1], q1);
0613 p2 = qd::two_prod(a[1], b[0], q2);
0614
0615 p3 = qd::two_prod(a[0], b[2], q3);
0616 p4 = qd::two_prod(a[1], b[1], q4);
0617 p5 = qd::two_prod(a[2], b[0], q5);
0618
0619
0620 qd::three_sum(p1, p2, q0);
0621
0622
0623 qd::three_sum(p2, q1, q2);
0624 qd::three_sum(p3, p4, p5);
0625
0626 s0 = qd::two_sum(p2, p3, t0);
0627 s1 = qd::two_sum(q1, p4, t1);
0628 s2 = q2 + p5;
0629 s1 = qd::two_sum(s1, t0, t0);
0630 s2 += (t0 + t1);
0631
0632
0633 p6 = qd::two_prod(a[0], b[3], q6);
0634 p7 = qd::two_prod(a[1], b[2], q7);
0635 p8 = qd::two_prod(a[2], b[1], q8);
0636 p9 = qd::two_prod(a[3], b[0], q9);
0637
0638
0639 q0 = qd::two_sum(q0, q3, q3);
0640 q4 = qd::two_sum(q4, q5, q5);
0641 p6 = qd::two_sum(p6, p7, p7);
0642 p8 = qd::two_sum(p8, p9, p9);
0643
0644 t0 = qd::two_sum(q0, q4, t1);
0645 t1 += (q3 + q5);
0646
0647 r0 = qd::two_sum(p6, p8, r1);
0648 r1 += (p7 + p9);
0649
0650 q3 = qd::two_sum(t0, r0, q4);
0651 q4 += (t1 + r1);
0652
0653 t0 = qd::two_sum(q3, s1, t1);
0654 t1 += q4;
0655
0656
0657 t1 += a[1] * b[3] + a[2] * b[2] + a[3] * b[1] + q6 + q7 + q8 + q9 + s2;
0658
0659 qd::renorm(p0, p1, s0, t0, t1);
0660 return qd_real(p0, p1, s0, t0);
0661 }
0662
0663 inline qd_real operator*(const qd_real &a, const qd_real &b) {
0664 #ifdef QD_SLOPPY_MUL
0665 return qd_real::sloppy_mul(a, b);
0666 #else
0667 return qd_real::accurate_mul(a, b);
0668 #endif
0669 }
0670
0671
0672
0673
0674 inline qd_real sqr(const qd_real &a) {
0675 double p0, p1, p2, p3, p4, p5;
0676 double q0, q1, q2, q3;
0677 double s0, s1;
0678 double t0, t1;
0679
0680 p0 = qd::two_sqr(a[0], q0);
0681 p1 = qd::two_prod(2.0 * a[0], a[1], q1);
0682 p2 = qd::two_prod(2.0 * a[0], a[2], q2);
0683 p3 = qd::two_sqr(a[1], q3);
0684
0685 p1 = qd::two_sum(q0, p1, q0);
0686
0687 q0 = qd::two_sum(q0, q1, q1);
0688 p2 = qd::two_sum(p2, p3, p3);
0689
0690 s0 = qd::two_sum(q0, p2, t0);
0691 s1 = qd::two_sum(q1, p3, t1);
0692
0693 s1 = qd::two_sum(s1, t0, t0);
0694 t0 += t1;
0695
0696 s1 = qd::quick_two_sum(s1, t0, t0);
0697 p2 = qd::quick_two_sum(s0, s1, t1);
0698 p3 = qd::quick_two_sum(t1, t0, q0);
0699
0700 p4 = 2.0 * a[0] * a[3];
0701 p5 = 2.0 * a[1] * a[2];
0702
0703 p4 = qd::two_sum(p4, p5, p5);
0704 q2 = qd::two_sum(q2, q3, q3);
0705
0706 t0 = qd::two_sum(p4, q2, t1);
0707 t1 = t1 + p5 + q3;
0708
0709 p3 = qd::two_sum(p3, t0, p4);
0710 p4 = p4 + q0 + t1;
0711
0712 qd::renorm(p0, p1, p2, p3, p4);
0713 return qd_real(p0, p1, p2, p3);
0714
0715 }
0716
0717
0718
0719 inline qd_real &qd_real::operator*=(double a) {
0720 *this = (*this * a);
0721 return *this;
0722 }
0723
0724
0725 inline qd_real &qd_real::operator*=(const dd_real &a) {
0726 *this = (*this * a);
0727 return *this;
0728 }
0729
0730
0731 inline qd_real &qd_real::operator*=(const qd_real &a) {
0732 *this = *this * a;
0733 return *this;
0734 }
0735
0736 inline qd_real operator/ (const qd_real &a, const dd_real &b) {
0737 #ifdef QD_SLOPPY_DIV
0738 return qd_real::sloppy_div(a, b);
0739 #else
0740 return qd_real::accurate_div(a, b);
0741 #endif
0742 }
0743
0744 inline qd_real operator/(const qd_real &a, const qd_real &b) {
0745 #ifdef QD_SLOPPY_DIV
0746 return qd_real::sloppy_div(a, b);
0747 #else
0748 return qd_real::accurate_div(a, b);
0749 #endif
0750 }
0751
0752
0753 inline qd_real operator/(double a, const qd_real &b) {
0754 return qd_real(a) / b;
0755 }
0756
0757
0758 inline qd_real operator/(const dd_real &a, const qd_real &b) {
0759 return qd_real(a) / b;
0760 }
0761
0762
0763
0764 inline qd_real &qd_real::operator/=(double a) {
0765 *this = (*this / a);
0766 return *this;
0767 }
0768
0769
0770 inline qd_real &qd_real::operator/=(const dd_real &a) {
0771 *this = (*this / a);
0772 return *this;
0773 }
0774
0775
0776 inline qd_real &qd_real::operator/=(const qd_real &a) {
0777 *this = (*this / a);
0778 return *this;
0779 }
0780
0781
0782
0783 inline qd_real qd_real::operator^(int n) const {
0784 return pow(*this, n);
0785 }
0786
0787
0788 inline qd_real abs(const qd_real &a) {
0789 return (a[0] < 0.0) ? -a : a;
0790 }
0791
0792 inline qd_real fabs(const qd_real &a) {
0793 return abs(a);
0794 }
0795
0796
0797
0798 inline qd_real quick_nint(const qd_real &a) {
0799 qd_real r = qd_real(qd::nint(a[0]), qd::nint(a[1]),
0800 qd::nint(a[2]), qd::nint(a[3]));
0801 r.renorm();
0802 return r;
0803 }
0804
0805
0806
0807 inline qd_real &qd_real::operator=(double a) {
0808 x[0] = a;
0809 x[1] = x[2] = x[3] = 0.0;
0810 return *this;
0811 }
0812
0813
0814 inline qd_real &qd_real::operator=(const dd_real &a) {
0815 x[0] = a._hi();
0816 x[1] = a._lo();
0817 x[2] = x[3] = 0.0;
0818 return *this;
0819 }
0820
0821
0822 inline bool operator==(const qd_real &a, double b) {
0823 return (a[0] == b && a[1] == 0.0 && a[2] == 0.0 && a[3] == 0.0);
0824 }
0825
0826 inline bool operator==(double a, const qd_real &b) {
0827 return (b == a);
0828 }
0829
0830 inline bool operator==(const qd_real &a, const dd_real &b) {
0831 return (a[0] == b._hi() && a[1] == b._lo() &&
0832 a[2] == 0.0 && a[3] == 0.0);
0833 }
0834
0835 inline bool operator==(const dd_real &a, const qd_real &b) {
0836 return (b == a);
0837 }
0838
0839 inline bool operator==(const qd_real &a, const qd_real &b) {
0840 return (a[0] == b[0] && a[1] == b[1] &&
0841 a[2] == b[2] && a[3] == b[3]);
0842 }
0843
0844
0845
0846 inline bool operator<(const qd_real &a, double b) {
0847 return (a[0] < b || (a[0] == b && a[1] < 0.0));
0848 }
0849
0850 inline bool operator<(double a, const qd_real &b) {
0851 return (b > a);
0852 }
0853
0854 inline bool operator<(const qd_real &a, const dd_real &b) {
0855 return (a[0] < b._hi() ||
0856 (a[0] == b._hi() && (a[1] < b._lo() ||
0857 (a[1] == b._lo() && a[2] < 0.0))));
0858 }
0859
0860 inline bool operator<(const dd_real &a, const qd_real &b) {
0861 return (b > a);
0862 }
0863
0864 inline bool operator<(const qd_real &a, const qd_real &b) {
0865 return (a[0] < b[0] ||
0866 (a[0] == b[0] && (a[1] < b[1] ||
0867 (a[1] == b[1] && (a[2] < b[2] ||
0868 (a[2] == b[2] && a[3] < b[3]))))));
0869 }
0870
0871
0872 inline bool operator>(const qd_real &a, double b) {
0873 return (a[0] > b || (a[0] == b && a[1] > 0.0));
0874 }
0875
0876 inline bool operator>(double a, const qd_real &b) {
0877 return (b < a);
0878 }
0879
0880 inline bool operator>(const qd_real &a, const dd_real &b) {
0881 return (a[0] > b._hi() ||
0882 (a[0] == b._hi() && (a[1] > b._lo() ||
0883 (a[1] == b._lo() && a[2] > 0.0))));
0884 }
0885
0886 inline bool operator>(const dd_real &a, const qd_real &b) {
0887 return (b < a);
0888 }
0889
0890 inline bool operator>(const qd_real &a, const qd_real &b) {
0891 return (a[0] > b[0] ||
0892 (a[0] == b[0] && (a[1] > b[1] ||
0893 (a[1] == b[1] && (a[2] > b[2] ||
0894 (a[2] == b[2] && a[3] > b[3]))))));
0895 }
0896
0897
0898
0899 inline bool operator<=(const qd_real &a, double b) {
0900 return (a[0] < b || (a[0] == b && a[1] <= 0.0));
0901 }
0902
0903 inline bool operator<=(double a, const qd_real &b) {
0904 return (b >= a);
0905 }
0906
0907 inline bool operator<=(const qd_real &a, const dd_real &b) {
0908 return (a[0] < b._hi() ||
0909 (a[0] == b._hi() && (a[1] < b._lo() ||
0910 (a[1] == b._lo() && a[2] <= 0.0))));
0911 }
0912
0913 inline bool operator<=(const dd_real &a, const qd_real &b) {
0914 return (b >= a);
0915 }
0916
0917 inline bool operator<=(const qd_real &a, const qd_real &b) {
0918 return (a[0] < b[0] ||
0919 (a[0] == b[0] && (a[1] < b[1] ||
0920 (a[1] == b[1] && (a[2] < b[2] ||
0921 (a[2] == b[2] && a[3] <= b[3]))))));
0922 }
0923
0924
0925 inline bool operator>=(const qd_real &a, double b) {
0926 return (a[0] > b || (a[0] == b && a[1] >= 0.0));
0927 }
0928
0929 inline bool operator>=(double a, const qd_real &b) {
0930 return (b <= a);
0931 }
0932
0933 inline bool operator>=(const qd_real &a, const dd_real &b) {
0934 return (a[0] > b._hi() ||
0935 (a[0] == b._hi() && (a[1] > b._lo() ||
0936 (a[1] == b._lo() && a[2] >= 0.0))));
0937 }
0938
0939 inline bool operator>=(const dd_real &a, const qd_real &b) {
0940 return (b <= a);
0941 }
0942
0943 inline bool operator>=(const qd_real &a, const qd_real &b) {
0944 return (a[0] > b[0] ||
0945 (a[0] == b[0] && (a[1] > b[1] ||
0946 (a[1] == b[1] && (a[2] > b[2] ||
0947 (a[2] == b[2] && a[3] >= b[3]))))));
0948 }
0949
0950
0951
0952
0953 inline bool operator!=(const qd_real &a, double b) {
0954 return !(a == b);
0955 }
0956
0957 inline bool operator!=(double a, const qd_real &b) {
0958 return !(a == b);
0959 }
0960
0961 inline bool operator!=(const qd_real &a, const dd_real &b) {
0962 return !(a == b);
0963 }
0964
0965 inline bool operator!=(const dd_real &a, const qd_real &b) {
0966 return !(a == b);
0967 }
0968
0969 inline bool operator!=(const qd_real &a, const qd_real &b) {
0970 return !(a == b);
0971 }
0972
0973
0974
0975 inline qd_real aint(const qd_real &a) {
0976 return (a[0] >= 0) ? floor(a) : ceil(a);
0977 }
0978
0979 inline bool qd_real::is_zero() const {
0980 return (x[0] == 0.0);
0981 }
0982
0983 inline bool qd_real::is_one() const {
0984 return (x[0] == 1.0 && x[1] == 0.0 && x[2] == 0.0 && x[3] == 0.0);
0985 }
0986
0987 inline bool qd_real::is_positive() const {
0988 return (x[0] > 0.0);
0989 }
0990
0991 inline bool qd_real::is_negative() const {
0992 return (x[0] < 0.0);
0993 }
0994
0995 inline dd_real to_dd_real(const qd_real &a) {
0996 return dd_real(a[0], a[1]);
0997 }
0998
0999 inline double to_double(const qd_real &a) {
1000 return a[0];
1001 }
1002
1003 inline int to_int(const qd_real &a) {
1004 return static_cast<int>(a[0]);
1005 }
1006
1007 inline qd_real inv(const qd_real &qd) {
1008 return 1.0 / qd;
1009 }
1010
1011 inline qd_real max(const qd_real &a, const qd_real &b) {
1012 return (a > b) ? a : b;
1013 }
1014
1015 inline qd_real max(const qd_real &a, const qd_real &b,
1016 const qd_real &c) {
1017 return (a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c);
1018 }
1019
1020 inline qd_real min(const qd_real &a, const qd_real &b) {
1021 return (a < b) ? a : b;
1022 }
1023
1024 inline qd_real min(const qd_real &a, const qd_real &b,
1025 const qd_real &c) {
1026 return (a < b) ? ((a < c) ? a : c) : ((b < c) ? b : c);
1027 }
1028
1029
1030 inline qd_real qd_real::rand() {
1031 return qdrand();
1032 }
1033
1034 inline qd_real ldexp(const qd_real &a, int n) {
1035 return qd_real(std::ldexp(a[0], n), std::ldexp(a[1], n),
1036 std::ldexp(a[2], n), std::ldexp(a[3], n));
1037 }
1038
1039 #endif