126 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			126 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C
		
	
	
	
| 
 | |
| /* @(#)z_ldexp.c 1.0 98/08/13 */
 | |
| 
 | |
| /*
 | |
| FUNCTION
 | |
|        <<ldexp>>, <<ldexpf>>---load exponent
 | |
| 
 | |
| INDEX
 | |
|         ldexp
 | |
| INDEX
 | |
|         ldexpf
 | |
| 
 | |
| ANSI_SYNOPSIS
 | |
|        #include <math.h>
 | |
|        double ldexp(double <[val]>, int <[exp]>);
 | |
|        float ldexpf(float <[val]>, int <[exp]>);
 | |
| 
 | |
| TRAD_SYNOPSIS
 | |
|        #include <math.h>
 | |
| 
 | |
|        double ldexp(<[val]>, <[exp]>)
 | |
|               double <[val]>;
 | |
|               int <[exp]>;
 | |
| 
 | |
|        float ldexpf(<[val]>, <[exp]>)
 | |
|               float <[val]>;
 | |
|               int <[exp]>;
 | |
| 
 | |
| DESCRIPTION
 | |
| <<ldexp>> calculates the value
 | |
| @ifnottex
 | |
| <[val]> times 2 to the power <[exp]>.
 | |
| @end ifnottex
 | |
| @tex
 | |
| $val\times 2^{exp}$.
 | |
| @end tex
 | |
| <<ldexpf>> is identical, save that it takes and returns <<float>>
 | |
| rather than <<double>> values.
 | |
| 
 | |
| RETURNS
 | |
| <<ldexp>> returns the calculated value.
 | |
| 
 | |
| Underflow and overflow both set <<errno>> to <<ERANGE>>.
 | |
| On underflow, <<ldexp>> and <<ldexpf>> return 0.0.
 | |
| On overflow, <<ldexp>> returns plus or minus <<HUGE_VAL>>.
 | |
| 
 | |
| PORTABILITY
 | |
| <<ldexp>> is ANSI. <<ldexpf>> is an extension.
 | |
| 
 | |
| */
 | |
| 
 | |
| /******************************************************************
 | |
|  * ldexp
 | |
|  *
 | |
|  * Input:
 | |
|  *   d - a floating point value
 | |
|  *   e - an exponent value
 | |
|  *
 | |
|  * Output:
 | |
|  *   A floating point value f such that f = d * 2 ^ e.
 | |
|  *
 | |
|  * Description:
 | |
|  *   This function creates a floating point number f such that
 | |
|  *   f = d * 2 ^ e.
 | |
|  *
 | |
|  *****************************************************************/
 | |
| 
 | |
| #include <float.h>
 | |
| #include "fdlibm.h"
 | |
| #include "zmath.h"
 | |
| 
 | |
| #ifndef _DOUBLE_IS_32BITS
 | |
| 
 | |
| #define DOUBLE_EXP_OFFS 1023
 | |
| 
 | |
| double
 | |
| _DEFUN (ldexp, (double, int),
 | |
|         double d _AND
 | |
|         int e)
 | |
| {
 | |
|   int exp;
 | |
|   __uint32_t hd;
 | |
| 
 | |
|   GET_HIGH_WORD (hd, d);
 | |
| 
 | |
|   /* Check for special values and then scale d by e. */
 | |
|   switch (numtest (d))
 | |
|     {
 | |
|       case NAN:
 | |
|         errno = EDOM;
 | |
|         break;
 | |
| 
 | |
|       case INF:
 | |
|         errno = ERANGE;
 | |
|         break;
 | |
| 
 | |
|       case 0:
 | |
|         break;
 | |
| 
 | |
|       default:
 | |
|         exp = (hd & 0x7ff00000) >> 20;
 | |
|         exp += e;
 | |
| 
 | |
|         if (exp > DBL_MAX_EXP + DOUBLE_EXP_OFFS)
 | |
|          {
 | |
|            errno = ERANGE;
 | |
|            d = z_infinity.d;
 | |
|          }
 | |
|         else if (exp < DBL_MIN_EXP + DOUBLE_EXP_OFFS)
 | |
|          {
 | |
|            errno = ERANGE;
 | |
|            d = -z_infinity.d;
 | |
|          }
 | |
|         else
 | |
|          {
 | |
|            hd &= 0x800fffff;
 | |
|            hd |= exp << 20;
 | |
|            SET_HIGH_WORD (d, hd);
 | |
|          }
 | |
|     }
 | |
| 
 | |
|     return (d);
 | |
| }
 | |
| 
 | |
| #endif /* _DOUBLE_IS_32BITS */
 |