s_csqrtf.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /*-
  2. * Copyright (c) 2007 David Schultz <das@FreeBSD.ORG>
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  15. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  16. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  17. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  18. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  19. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  20. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  21. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  22. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  23. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  24. * SUCH DAMAGE.
  25. */
  26. #include "cdefs-compat.h"
  27. //__FBSDID("$FreeBSD: src/lib/msun/src/s_csqrtf.c,v 1.3 2008/08/08 00:15:16 das Exp $");
  28. #include <openlibm_complex.h>
  29. #include <openlibm_math.h>
  30. #include "math_private.h"
  31. /*
  32. * gcc doesn't implement complex multiplication or division correctly,
  33. * so we need to handle infinities specially. We turn on this pragma to
  34. * notify conforming c99 compilers that the fast-but-incorrect code that
  35. * gcc generates is acceptable, since the special cases have already been
  36. * handled.
  37. */
  38. #ifndef __GNUC__
  39. #pragma STDC CX_LIMITED_RANGE ON
  40. #endif
  41. DLLEXPORT float complex
  42. csqrtf(float complex z)
  43. {
  44. float a = crealf(z), b = cimagf(z);
  45. double t;
  46. /* Handle special cases. */
  47. if (z == 0)
  48. return (CMPLXF(0, b));
  49. if (isinf(b))
  50. return (CMPLXF(INFINITY, b));
  51. if (isnan(a)) {
  52. t = (b - b) / (b - b); /* raise invalid if b is not a NaN */
  53. return (CMPLXF(a, t)); /* return NaN + NaN i */
  54. }
  55. if (isinf(a)) {
  56. /*
  57. * csqrtf(inf + NaN i) = inf + NaN i
  58. * csqrtf(inf + y i) = inf + 0 i
  59. * csqrtf(-inf + NaN i) = NaN +- inf i
  60. * csqrtf(-inf + y i) = 0 + inf i
  61. */
  62. if (signbit(a))
  63. return (CMPLXF(fabsf(b - b), copysignf(a, b)));
  64. else
  65. return (CMPLXF(a, copysignf(b - b, b)));
  66. }
  67. /*
  68. * The remaining special case (b is NaN) is handled just fine by
  69. * the normal code path below.
  70. */
  71. /*
  72. * We compute t in double precision to avoid overflow and to
  73. * provide correct rounding in nearly all cases.
  74. * This is Algorithm 312, CACM vol 10, Oct 1967.
  75. */
  76. if (a >= 0) {
  77. t = sqrt((a + hypot(a, b)) * 0.5);
  78. return (CMPLXF(t, b / (2.0 * t)));
  79. } else {
  80. t = sqrt((-a + hypot(a, b)) * 0.5);
  81. return (CMPLXF(fabsf(b) / (2.0 * t), copysignf(t, b)));
  82. }
  83. }