hypotf.c 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /* origin: FreeBSD /usr/src/lib/msun/src/e_hypotf.c */
  2. /*
  3. * Conversion to float by Ian Lance Taylor, Cygnus Support, [email protected].
  4. */
  5. /*
  6. * ====================================================
  7. * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  8. *
  9. * Developed at SunPro, a Sun Microsystems, Inc. business.
  10. * Permission to use, copy, modify, and distribute this
  11. * software is freely granted, provided that this notice
  12. * is preserved.
  13. * ====================================================
  14. */
  15. #include "libm.h"
  16. float hypotf(float x, float y)
  17. {
  18. float a,b,t1,t2,y1,y2,w;
  19. int32_t j,k,ha,hb;
  20. GET_FLOAT_WORD(ha,x);
  21. ha &= 0x7fffffff;
  22. GET_FLOAT_WORD(hb,y);
  23. hb &= 0x7fffffff;
  24. if (hb > ha) {
  25. a = y;
  26. b = x;
  27. j=ha; ha=hb; hb=j;
  28. } else {
  29. a = x;
  30. b = y;
  31. }
  32. a = fabsf(a);
  33. b = fabsf(b);
  34. if (ha - hb > 0xf000000) /* x/y > 2**30 */
  35. return a+b;
  36. k = 0;
  37. if (ha > 0x58800000) { /* a > 2**50 */
  38. if(ha >= 0x7f800000) { /* Inf or NaN */
  39. /* Use original arg order iff result is NaN; quieten sNaNs. */
  40. w = fabsf(x+0.0f) - fabsf(y+0.0f);
  41. if (ha == 0x7f800000) w = a;
  42. if (hb == 0x7f800000) w = b;
  43. return w;
  44. }
  45. /* scale a and b by 2**-68 */
  46. ha -= 0x22000000; hb -= 0x22000000; k += 68;
  47. SET_FLOAT_WORD(a, ha);
  48. SET_FLOAT_WORD(b, hb);
  49. }
  50. if (hb < 0x26800000) { /* b < 2**-50 */
  51. if (hb <= 0x007fffff) { /* subnormal b or 0 */
  52. if (hb == 0)
  53. return a;
  54. SET_FLOAT_WORD(t1, 0x7e800000); /* t1 = 2^126 */
  55. b *= t1;
  56. a *= t1;
  57. k -= 126;
  58. } else { /* scale a and b by 2^68 */
  59. ha += 0x22000000; /* a *= 2^68 */
  60. hb += 0x22000000; /* b *= 2^68 */
  61. k -= 68;
  62. SET_FLOAT_WORD(a, ha);
  63. SET_FLOAT_WORD(b, hb);
  64. }
  65. }
  66. /* medium size a and b */
  67. w = a - b;
  68. if (w > b) {
  69. SET_FLOAT_WORD(t1, ha&0xfffff000);
  70. t2 = a - t1;
  71. w = sqrtf(t1*t1-(b*(-b)-t2*(a+t1)));
  72. } else {
  73. a = a + a;
  74. SET_FLOAT_WORD(y1, hb&0xfffff000);
  75. y2 = b - y1;
  76. SET_FLOAT_WORD(t1,(ha+0x00800000)&0xfffff000);
  77. t2 = a - t1;
  78. w = sqrtf(t1*y1-(w*(-w)-(t1*y2+t2*b)));
  79. }
  80. if (k)
  81. w = scalbnf(w, k);
  82. return w;
  83. }