/newlib/libm/complex/csqrt.c

https://bitbucket.org/pizzafactory/binutils · C · 137 lines · 64 code · 7 blank · 66 comment · 16 complexity · 9bc43b9c289ef20784fa9a967379d668 MD5 · raw file

  1. /* $NetBSD: csqrt.c,v 1.1 2007/08/20 16:01:37 drochner Exp $ */
  2. /*-
  3. * Copyright (c) 2007 The NetBSD Foundation, Inc.
  4. * All rights reserved.
  5. *
  6. * This code is derived from software written by Stephen L. Moshier.
  7. * It is redistributed by the NetBSD Foundation by permission of the author.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  19. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  20. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  21. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
  22. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  23. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  24. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  25. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  26. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  27. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  28. * POSSIBILITY OF SUCH DAMAGE.
  29. *
  30. * imported and modified include for newlib 2010/10/03
  31. * Marco Atzeri <marco_atzeri@yahoo.it>
  32. */
  33. /*
  34. FUNCTION
  35. <<csqrt>>, <<csqrtf>>---complex square root
  36. INDEX
  37. csqrt
  38. INDEX
  39. csqrtf
  40. ANSI_SYNOPSIS
  41. #include <complex.h>
  42. double complex csqrt(double complex <[z]>);
  43. float complex csqrtf(float complex <[z]>);
  44. DESCRIPTION
  45. These functions compute the complex square root of <[z]>, with
  46. a branch cut along the negative real axis.
  47. <<csqrtf>> is identical to <<csqrt>>, except that it performs
  48. its calculations on <<floats complex>>.
  49. RETURNS
  50. The csqrt functions return the complex square root value, in
  51. the range of the right halfplane (including the imaginary axis).
  52. PORTABILITY
  53. <<csqrt>> and <<csqrtf>> are ISO C99
  54. QUICKREF
  55. <<csqrt>> and <<csqrtf>> are ISO C99
  56. */
  57. #include <complex.h>
  58. #include <math.h>
  59. double complex
  60. csqrt(double complex z)
  61. {
  62. double complex w;
  63. double x, y, r, t, scale;
  64. x = creal (z);
  65. y = cimag (z);
  66. if (y == 0.0) {
  67. if (x == 0.0) {
  68. w = 0.0 + y * I;
  69. } else {
  70. r = fabs(x);
  71. r = sqrt(r);
  72. if (x < 0.0) {
  73. w = 0.0 + r * I;
  74. } else {
  75. w = r + y * I;
  76. }
  77. }
  78. return w;
  79. }
  80. if (x == 0.0) {
  81. r = fabs(y);
  82. r = sqrt(0.5 * r);
  83. if (y > 0)
  84. w = r + r * I;
  85. else
  86. w = r - r * I;
  87. return w;
  88. }
  89. /* Rescale to avoid internal overflow or underflow. */
  90. if ((fabs(x) > 4.0) || (fabs(y) > 4.0)) {
  91. x *= 0.25;
  92. y *= 0.25;
  93. scale = 2.0;
  94. } else {
  95. #if 1
  96. x *= 1.8014398509481984e16; /* 2^54 */
  97. y *= 1.8014398509481984e16;
  98. scale = 7.450580596923828125e-9; /* 2^-27 */
  99. #else
  100. x *= 4.0;
  101. y *= 4.0;
  102. scale = 0.5;
  103. #endif
  104. }
  105. w = x + y * I;
  106. r = cabs(w);
  107. if (x > 0) {
  108. t = sqrt(0.5 * r + 0.5 * x);
  109. r = scale * fabs((0.5 * y) / t );
  110. t *= scale;
  111. } else {
  112. r = sqrt(0.5 * r - 0.5 * x);
  113. t = scale * fabs((0.5 * y) / r);
  114. r *= scale;
  115. }
  116. if (y < 0)
  117. w = t - r * I;
  118. else
  119. w = t + r * I;
  120. return w;
  121. }