/ src / ref / ceilf.c
ceilf.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(ceilf)(float x)
33  {
34    float r;
35    int rexp, xneg;
36    unsigned int ux, ax, ur, mask;
37  
38    GET_BITS_SP32(x, ux);
39    /*ax is |x|*/
40    ax = ux & (~SIGNBIT_SP32);
41    /*xneg stores the sign of the input x*/
42    xneg = (ux != ax);
43    /*The range is divided into
44      > 2^24. ceil will either the number itself or Nan
45              always returns a QNan. Raises exception if input is a SNan
46      < 1.0   If 0.0 then return with the appropriate sign
47              If input is less than -0.0 and greater than -1.0 then return -0.0
48              If input is greater than 0.0 and less than 1.0 then return 1.0
49      1.0 < |x| < 2^24
50              appropriately check the exponent and set the return Value by shifting
51              */
52    if (ax >= 0x4b800000) /* abs(x) > 2^24*/
53      {
54        /* abs(x) is either NaN, infinity, or >= 2^24 */
55        if (ax > 0x7f800000)
56          /* x is NaN */
57              #ifdef WINDOWS
58                  return __amd_handle_errorf("ceilf", __amd_ceil, ux|0x00400000, _DOMAIN, 0, EDOM, x, 0.0, 1);
59              #else
60                  if(!(ax & 0x00400000)) //x is snan
61                      return __amd_handle_errorf("ceilf", __amd_ceil, ux|0x00400000, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0, 1);
62  		else
63  			return x;
64              #endif
65  
66        else
67          return x;
68      }
69    else if (ax < 0x3f800000) /* abs(x) < 1.0 */
70      {
71        if (ax == 0x00000000)
72          /* x is +zero or -zero; return the same zero */
73          return x;
74        else if (xneg) /* x < 0.0 */
75          return -0.0F;
76        else
77          return 1.0F;
78      }
79    else
80      {
81        rexp = ((ux & EXPBITS_SP32) >> EXPSHIFTBITS_SP32) - EXPBIAS_SP32;
82        /* Mask out the bits of r that we don't want */
83        mask = (1 << (EXPSHIFTBITS_SP32 - rexp)) - 1;
84        /*Keeps the exponent part and the required mantissa.*/
85        ur = (ux & ~mask);
86        PUT_BITS_SP32(ur, r);
87  
88        if (xneg || (ux == ur)) return r;
89        else
90          /* We threw some bits away and x was positive */
91          return r + 1.0F;
92      }
93  }
94  
95