]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/language/c/libm/v2_0/src/double/portable-api/s_scalbn.c
Initial revision
[karo-tx-redboot.git] / packages / language / c / libm / v2_0 / src / double / portable-api / s_scalbn.c
1 //===========================================================================
2 //
3 //      s_scalbn.c
4 //
5 //      Part of the standard mathematical function library
6 //
7 //===========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 //
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //===========================================================================
41 //#####DESCRIPTIONBEGIN####
42 //
43 // Author(s):   jlarmour
44 // Contributors:  jlarmour
45 // Date:        1998-02-13
46 // Purpose:     
47 // Description: 
48 // Usage:       
49 //
50 //####DESCRIPTIONEND####
51 //
52 //===========================================================================
53
54 // CONFIGURATION
55
56 #include <pkgconf/libm.h>   // Configuration header
57
58 // Include the Math library?
59 #ifdef CYGPKG_LIBM     
60
61 // Derived from code with the following copyright
62
63
64 /* @(#)s_scalbn.c 1.3 95/01/18 */
65 /*
66  * ====================================================
67  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
68  *
69  * Developed at SunSoft, a Sun Microsystems, Inc. business.
70  * Permission to use, copy, modify, and distribute this
71  * software is freely granted, provided that this notice 
72  * is preserved.
73  * ====================================================
74  */
75
76 /* 
77  * scalbn (double x, int n)
78  * scalbn(x,n) returns x* 2**n  computed by  exponent  
79  * manipulation rather than by actually performing an 
80  * exponentiation or a multiplication.
81  */
82
83 #include "mathincl/fdlibm.h"
84
85 static const double
86 two54   =  1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
87 twom54  =  5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
88 huge   = 1.0e+300,
89 tiny   = 1.0e-300;
90
91         double scalbn (double x, int n)
92 {
93         int  k,hx,lx;
94         hx = CYG_LIBM_HI(x);
95         lx = CYG_LIBM_LO(x);
96         k = (hx&0x7ff00000)>>20;                /* extract exponent */
97         if (k==0) {                             /* 0 or subnormal x */
98             if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */
99             x *= two54; 
100             hx = CYG_LIBM_HI(x);
101             k = ((hx&0x7ff00000)>>20) - 54; 
102             if (n< -50000) return tiny*x;       /*underflow*/
103             }
104         if (k==0x7ff) return x+x;               /* NaN or Inf */
105         k = k+n; 
106         if (k >  0x7fe) return huge*copysign(huge,x); /* overflow  */
107         if (k > 0)                              /* normal result */
108             {CYG_LIBM_HI(x) = (hx&0x800fffff)|(k<<20); return x;}
109         if (k <= -54) {
110             if (n > 50000)      /* in case integer overflow in n+k */
111                 return huge*copysign(huge,x);   /*overflow*/
112             else return tiny*copysign(tiny,x);  /*underflow*/
113         }
114         k += 54;                                /* subnormal result */
115         CYG_LIBM_HI(x) = (hx&0x800fffff)|(k<<20);
116         return x*twom54;
117 }
118
119 #endif // ifdef CYGPKG_LIBM     
120
121 // EOF s_scalbn.c