/ src / ref / roundf.c
roundf.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 "fn_macros.h"
29  #include "libm_util_amd.h"
30  #include "libm_special.h"
31  
32  float FN_PROTOTYPE_REF(roundf)(float f)
33  {
34      UT32 u32f, u32Temp;
35      U32 u32sign, u32exp, u32mantissa;
36      int intexp;            /*Needs to be signed */
37      u32f.f32 = f;
38      u32sign = u32f.u32 & SIGNBIT_SP32;
39      if ((u32f.u32 & 0X7F800000) == 0x7F800000)
40      {
41          //u32f.f32 = f;
42          /*Return Quiet Nan.
43           * Quiet the signalling nan*/
44          if(!((u32f.u32 & MANTBITS_SP32) == 0))
45          {
46              #ifdef WINDOWS
47  			return __amd_handle_errorf("roundf", __amd_round, u32f.u32 |= QNAN_MASK_32, _DOMAIN, 0, EDOM, f, 0.0, 1);
48              #else
49                  if(!(u32f.u32 & 0x00400000)) //x is snan
50  			return __amd_handle_errorf("roundf", __amd_round, u32f.u32, _DOMAIN, AMD_F_INVALID, EDOM, f, 0.0, 1);
51  		else
52  			return u32f.f32;
53              #endif
54  		}
55          /*else the number is infinity*/
56          //Raise range or domain error
57  		return __amd_handle_errorf("roundf", __amd_round, u32f.u32, _DOMAIN, 0, EDOM, f, 0.0, 1);
58      }
59      /*Get the exponent of the input*/
60      intexp = (u32f.u32 & 0x7f800000) >> 23;
61      intexp -= 0x7F;
62      /*If exponent is greater than 22 then the number is already
63        rounded*/
64      if (intexp > 22)
65          return f;
66      if (intexp < 0)
67      {
68          u32Temp.f32 = f;
69          u32Temp.u32 &= 0x7FFFFFFF;
70          /*Add with a large number (2^23 +1) = 8388609.0F
71          to force an overflow*/
72          u32Temp.f32 = (u32Temp.f32 + 8388609.0F);
73          /*Substract back with t he large number*/
74          u32Temp.f32 -= 8388609;
75          if (u32sign)
76              u32Temp.u32 |= 0x80000000;
77          return u32Temp.f32;
78      }
79      else
80      {
81          /*if(intexp == -1)
82              u32exp = 0x3F800000;       */
83          u32f.u32 &= 0x7FFFFFFF;
84          u32f.f32 += 0.5;
85          u32exp = u32f.u32 & 0x7F800000;
86          /*right shift then left shift to discard the decimal
87            places*/
88          u32mantissa = (u32f.u32 & MANTBITS_SP32) >> (23 - intexp);
89          u32mantissa = u32mantissa << (23 - intexp);
90          u32Temp.u32 = u32sign | u32exp | u32mantissa;
91          return (u32Temp.f32);
92      }
93  }
94  
95