1 // Copyright (C) 2019 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #ifndef ICING_UTIL_MATH_UTIL_H_
16 #define ICING_UTIL_MATH_UTIL_H_
17
18 #include <cstdint>
19 #include <limits>
20
21 namespace icing {
22 namespace lib {
23
24 namespace math_util {
25
SafeDivide(double first,double second)26 inline double SafeDivide(double first, double second) {
27 if (second == 0) {
28 return std::numeric_limits<double>::infinity();
29 }
30 return first / second;
31 }
32
33 // Returns the maximum integer value which is a multiple of rounding_value,
34 // and less than or equal to input_value.
35 //
36 // input_value must be greater than or equal to zero, or else returns 0.
37 // rounding_value must be greater than or equal to zero, or else returns 0.
38 template <typename IntType>
RoundDownTo(IntType input_value,IntType rounding_value)39 static IntType RoundDownTo(IntType input_value, IntType rounding_value) {
40 static_assert(std::numeric_limits<IntType>::is_integer,
41 "RoundDownTo() operation type is not integer");
42
43 if (input_value <= 0) {
44 return 0;
45 }
46
47 if (rounding_value <= 0) {
48 return 0;
49 }
50
51 return (input_value / rounding_value) * rounding_value;
52 }
53
54 // Returns the minimum integer value which is a multiple of rounding_value,
55 // and greater than or equal to input_value.
56 //
57 // input_value must be greater than or equal to zero, or else returns 0.
58 // rounding_value must be greater than or equal to zero, or else returns 0.
59 template <typename IntType>
RoundUpTo(IntType input_value,IntType rounding_value)60 static IntType RoundUpTo(IntType input_value, IntType rounding_value) {
61 static_assert(std::numeric_limits<IntType>::is_integer,
62 "RoundUpTo() operation type is not integer");
63
64 if (input_value <= 0) {
65 return 0;
66 }
67
68 if (rounding_value <= 0) {
69 return 0;
70 }
71
72 const IntType remainder = input_value % rounding_value;
73 return (remainder == 0) ? input_value
74 : (input_value - remainder + rounding_value);
75 }
76
77 // Returns the next power of 2 given n (the smallest power of 2 which is
78 // greater or equal to n).
79 //
80 // REQUIRES: n <= 2^31, since 2^31 is the largest power of 2 that can be
81 // represented by an unsigned int.
NextPowerOf2(uint32_t n)82 inline uint32_t NextPowerOf2(uint32_t n) {
83 if (n == 0) {
84 return 1;
85 }
86
87 if ((n & (n - 1)) != 0) {
88 // not 2's power
89 return UINT32_C(1) << (32 - __builtin_clz(n));
90 }
91 return n;
92 }
93
94 } // namespace math_util
95
96 } // namespace lib
97 } // namespace icing
98
99 #endif // ICING_UTIL_MATH_UTIL_H_
100