xref: /reactos/sdk/lib/crt/math/ceil.c (revision 98e8827a)
1 /*
2  * PROJECT:     ReactOS CRT library
3  * LICENSE:     MIT (https://spdx.org/licenses/MIT)
4  * PURPOSE:     Portable implementation of ceil
5  * COPYRIGHT:   Copyright 2021 Timo Kreuzer <timo.kreuzer@reactos.org>
6  */
7 
8 #define _USE_MATH_DEFINES
9 #include <math.h>
10 #include <limits.h>
11 
12 #ifdef _MSC_VER
13 #pragma function(ceil)
14 #endif
15 
16 double
17 __cdecl
18 ceil(double x)
19 {
20     /* Load the value as uint64 */
21     unsigned long long u64 = *(unsigned long long*)&x;
22 
23     /* Check for NAN */
24     if ((u64 & ~(1ULL << 63)) > 0x7FF0000000000000ull)
25     {
26         /* Set error bit */
27         u64 |= 0x0008000000000000ull;
28         return *(double*)&u64;
29     }
30 
31     /* Check if x is positive */
32     if ((u64 & (1ULL << 63)) == 0)
33     {
34         /* Check if it fits into an int64 */
35         if (x < (double)_I64_MAX)
36         {
37             /* Cast to int64 to truncate towards 0. If this matches the
38                input, return it as is, otherwise add 1 */
39             double y = (double)(long long)x;
40             return (x > y) ? y + 1 : y;
41         }
42         else
43         {
44             /* The exponent is larger than the fraction bits.
45                This means the number is already an integer. */
46             return x;
47         }
48     }
49     else
50     {
51         /* Check if it fits into an int64 */
52         if (x > (double)_I64_MIN)
53         {
54             /* Cast to int64 to truncate towards 0. */
55             x = (double)(long long)x;
56             return (x == 0.) ? -0.0 : x;
57         }
58         else
59         {
60             /* The exponent is larger than the fraction bits.
61                This means the number is already an integer. */
62             return x;
63         }
64     }
65 }
66