ldexp.c 967 B

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. /*
  2. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. */
  5. /* $Id$ */
  6. #include <math.h>
  7. #include <float.h>
  8. #include <errno.h>
  9. double
  10. ldexp(double fl, int exp)
  11. {
  12. int sign = 1;
  13. int currexp;
  14. if (__IsNan(fl)) {
  15. errno = EDOM;
  16. return fl;
  17. }
  18. if (fl == 0.0) return 0.0;
  19. if (fl<0) {
  20. fl = -fl;
  21. sign = -1;
  22. }
  23. if (fl > DBL_MAX) { /* for infinity */
  24. errno = ERANGE;
  25. return sign * fl;
  26. }
  27. fl = frexp(fl,&currexp);
  28. exp += currexp;
  29. if (exp > 0) {
  30. if (exp > DBL_MAX_EXP) {
  31. errno = ERANGE;
  32. return sign * HUGE_VAL;
  33. }
  34. while (exp>30) {
  35. fl *= (double) (1L << 30);
  36. exp -= 30;
  37. }
  38. fl *= (double) (1L << exp);
  39. }
  40. else {
  41. /* number need not be normalized */
  42. if (exp < DBL_MIN_EXP - DBL_MANT_DIG) {
  43. return 0.0;
  44. }
  45. while (exp<-30) {
  46. fl /= (double) (1L << 30);
  47. exp += 30;
  48. }
  49. fl /= (double) (1L << -exp);
  50. }
  51. return sign * fl;
  52. }