/ src / ref / frexp.c
frexp.c
 1  /*
 2   * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved.
 3   *
 4   * Redistribution and use in source and binary forms, with or without modification,
 5   * are permitted provided that the following conditions are met:
 6   * 1. Redistributions of source code must retain the above copyright notice,
 7   *    this list of conditions and the following disclaimer.
 8   * 2. Redistributions in binary form must reproduce the above copyright notice,
 9   *    this list of conditions and the following disclaimer in the documentation
10   *    and/or other materials provided with the distribution.
11   * 3. Neither the name of the copyright holder nor the names of its contributors
12   *    may be used to endorse or promote products derived from this software without
13   *    specific prior written permission.
14   *
15   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18   * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
19   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20   * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
21   * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24   * POSSIBILITY OF SUCH DAMAGE.
25   *
26   */
27  
28  #include "libm_amd.h"
29  #include "libm_util_amd.h"
30  #include "libm_special.h"
31  
32  
33  double FN_PROTOTYPE_REF(frexp)(double value, int *exp)
34  {
35      UT64 val;
36      unsigned int sign;
37      int exponent;
38      val.f64 = value;
39      sign = val.u32[1] & SIGNBIT_SP32;
40      val.u32[1] = val.u32[1] & ~SIGNBIT_SP32; /* remove the sign bit */
41      *exp = 0;
42      if((val.u64 == 0x0000000000000000) || (val.u64 == 0x7ff0000000000000))
43          return value; /* value= +-0 or value= nan or value = +-inf return value */
44      
45      if(val.u64 > 0x7ff0000000000000)
46      {
47  #ifdef WINDOWS
48           return __amd_handle_error("frexp", __amd_frexp, val.u64|QNANBITPATT_DP64, DOMAIN, AMD_F_NONE, EDOM,value, 0.0, 1);
49  #else
50           return value+value;
51  #endif
52      }
53      exponent = val.u32[1] >> 20; /* get the exponent */
54  
55      if(exponent == 0)/*x is denormal*/
56      {
57  		val.f64 = val.f64 * VAL_2PMULTIPLIER_DP;/*multiply by 2^53 to bring it to the normal range*/
58          exponent = val.u32[1] >> 20; /* get the exponent */
59  		exponent = exponent - MULTIPLIER_DP;
60      }
61  
62  	exponent -= 1022; /* remove bias(1023)-1 */
63      *exp = exponent; /* set the integral power of two */
64      val.u32[1] = sign | 0x3fe00000 | (val.u32[1] & 0x000fffff);/* make the fractional part(divide by 2) */                                              
65      return val.f64;
66  }
67  
68