scalb.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. #if defined(__ppc__)
  2. /***********************************************************************
  3. ** File: scalb.c
  4. **
  5. ** Contains: C source code for implementations of floating-point
  6. ** scalb functions defined in header <fp.h>. In
  7. ** particular, this file contains implementations of
  8. ** functions scalb and scalbl for double and long double
  9. ** formats on PowerPC platforms.
  10. **
  11. ** Written by: Jon Okada, SANEitation Engineer, ext. 4-4838
  12. **
  13. ** Copyright: © 1992 by Apple Computer, Inc., all rights reserved
  14. **
  15. ** Change History ( most recent first ):
  16. **
  17. ** 28 May 97 ali made an speed improvement for large n,
  18. ** removed scalbl.
  19. ** 12 Dec 92 JPO First created.
  20. **
  21. ***********************************************************************/
  22. typedef union
  23. {
  24. struct {
  25. #if defined(__BIG_ENDIAN__)
  26. unsigned long int hi;
  27. unsigned long int lo;
  28. #else
  29. unsigned long int lo;
  30. unsigned long int hi;
  31. #endif
  32. } words;
  33. double dbl;
  34. } DblInHex;
  35. static const double twoTo1023 = 8.988465674311579539e307; // 0x1p1023
  36. static const double twoToM1022 = 2.225073858507201383e-308; // 0x1p-1022
  37. /***********************************************************************
  38. double scalb( double x, long int n ) returns its argument x scaled
  39. by the factor 2^m. NaNs, signed zeros, and infinities are propagated
  40. by this function regardless of the value of n.
  41. Exceptions: OVERFLOW/INEXACT or UNDERFLOW inexact may occur;
  42. INVALID for signaling NaN inputs ( quiet NaN returned ).
  43. Calls: none.
  44. ***********************************************************************/
  45. double scalb ( double x, int n )
  46. {
  47. DblInHex xInHex;
  48. xInHex.words.lo = 0UL; // init. low half of xInHex
  49. if ( n > 1023 )
  50. { // large positive scaling
  51. if ( n > 2097 ) // huge scaling
  52. return ( ( x * twoTo1023 ) * twoTo1023 ) * twoTo1023;
  53. while ( n > 1023 )
  54. { // scale reduction loop
  55. x *= twoTo1023; // scale x by 2^1023
  56. n -= 1023; // reduce n by 1023
  57. }
  58. }
  59. else if ( n < -1022 )
  60. { // large negative scaling
  61. if ( n < -2098 ) // huge negative scaling
  62. return ( ( x * twoToM1022 ) * twoToM1022 ) * twoToM1022;
  63. while ( n < -1022 )
  64. { // scale reduction loop
  65. x *= twoToM1022; // scale x by 2^( -1022 )
  66. n += 1022; // incr n by 1022
  67. }
  68. }
  69. /*******************************************************************************
  70. * -1022 <= n <= 1023; convert n to double scale factor. *
  71. *******************************************************************************/
  72. xInHex.words.hi = ( ( unsigned long ) ( n + 1023 ) ) << 20;
  73. return ( x * xInHex.dbl );
  74. }
  75. #endif /* __ppc__ */