283{
284
285
286
287
288
289
290
291 if (mpfr_zero_p(a->re) && mpfr_zero_p(a->im))
292 {
293 mpfr_set_si(
result->re, 0, MPFR_RNDN);
294 mpfr_set_si(
result->im, 0, MPFR_RNDN);
295 return;
296 }
297
298 mpfr_t b, c, d, d2;
299
300 unsigned long p = mpfr_get_prec(a->re);
305
306
307
308 mpfr_abs(b, a->re, MPFR_RNDN);
309 mpfr_abs(c, a->im, MPFR_RNDN);
310 if (mpfr_greater_p(b, c))
311 {
312
313
314
315 mpfr_div(d, c, b, MPFR_RNDN);
316 mpfr_sqr(d, d, MPFR_RNDN);
317 mpfr_add_si(d, d, 1, MPFR_RNDN);
318 mpfr_sqrt(d, d, MPFR_RNDN);
319 mpfr_add_si(d, d, 1, MPFR_RNDN);
320 mpfr_div_2ui(d, d, 1, MPFR_RNDN);
321 mpfr_sqrt(d, d, MPFR_RNDN);
322 mpfr_sqrt(b, b, MPFR_RNDN);
323 mpfr_mul(d, d, b, MPFR_RNDN);
324 }
325 else
326 {
327
328
329 mpfr_div(d, b, c, MPFR_RNDN);
330 mpfr_sqr(d2, d, MPFR_RNDN);
331 mpfr_add_si(d2, d2, 1, MPFR_RNDN);
332 mpfr_sqrt(d2, d2, MPFR_RNDN);
333 mpfr_add(d, d2, d, MPFR_RNDN);
334 mpfr_div_2ui(d, d, 1, MPFR_RNDN);
335 mpfr_sqrt(d, d, MPFR_RNDN);
336 mpfr_sqrt(c, c, MPFR_RNDN);
337 mpfr_mul(d, d, c, MPFR_RNDN);
338 }
339 if (mpfr_sgn(a->re) >= 0)
340 {
341
342
343 mpfr_set(
result->re, d, MPFR_RNDN);
344 mpfr_mul_2ui(d, d, 1, MPFR_RNDN);
345 mpfr_div(
result->im, a->im, d, MPFR_RNDN);
346 }
347 else
348 {
349
350
351 mpfr_set(
result->im, d, MPFR_RNDN);
352 if (mpfr_sgn(a->im) < 0) mpfr_neg(
result->im,
result->im, MPFR_RNDN);
353 mpfr_mul_2ui(d,
result->im, 1, MPFR_RNDN);
354 mpfr_div(
result->re, a->im, d, MPFR_RNDN);
355 }
356
357 mpfr_clear(b);
358 mpfr_clear(c);
359 mpfr_clear(d);
360 mpfr_clear(d2);
361
362#if 0
364 {
365 double b,c,d,e;
366 if (a.re == 0.0 && a.im == 0.0)
367 {
370 }
371 else
372 {
375 if (b > c)
376 {
377 d = c/b;
378 e = ::sqrt(b) * ::sqrt(0.5 * (1.0 + ::sqrt(1.0 + d*d)));
379 }
380 else
381 {
382 d = b/c;
383 e = ::sqrt(c) * ::sqrt(0.5 * (d + ::sqrt(1.0 + d*d)));
384 }
385
386 if (a.re >= 0.0)
387 {
389 result.im = a.im/(2.0 * e);
390 }
391 else
392 {
393 result.im = (a.im >= 0.0 ? e : -e);
395 }
396 }
397 }
398#endif
399}
VALGRIND_MAKE_MEM_DEFINED & result(result)
const mpreal sqrt(const unsigned int v, mp_rnd_t rnd_mode=mpreal::get_default_rnd())
const mpreal fabs(const mpreal &x, mp_rnd_t r=mpreal::get_default_rnd())