1 /* 2 * PROJECT: ReactOS CRT library 3 * LICENSE: MIT (https://spdx.org/licenses/MIT) 4 * PURPOSE: Implementation of floor 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(floor) 14 #endif 15 16 double 17 __cdecl 18 floor(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 /* Just cast to int64, which will truncate towards 0, 38 which is what we want here.*/ 39 return (double)(long long)x; 40 } 41 else 42 { 43 /* The exponent is larger than the fraction bits. 44 This means the number is already an integer. */ 45 return x; 46 } 47 } 48 else 49 { 50 /* Check if it fits into an int64 */ 51 if (x > (double)_I64_MIN) 52 { 53 /* Check if it is -0 */ 54 if (x == -0.) 55 { 56 return -0.; 57 } 58 59 /* Cast to int64 to truncate towards 0. If this matches the 60 input, return it as is, otherwise subtract 1 */ 61 double y = (double)(long long)x; 62 return (x == y) ? y : y - 1; 63 } 64 else 65 { 66 /* The exponent is larger than the fraction bits. 67 This means the number is already an integer. */ 68 return x; 69 } 70 } 71 } 72