/src/geos/src/deps/ryu/common.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2018 Ulf Adams |
2 | | // |
3 | | // The contents of this file may be used under the terms of the Apache License, |
4 | | // Version 2.0. |
5 | | // |
6 | | // (See accompanying file LICENSE-Apache or copy at |
7 | | // http://www.apache.org/licenses/LICENSE-2.0) |
8 | | // |
9 | | // Alternatively, the contents of this file may be used under the terms of |
10 | | // the Boost Software License, Version 1.0. |
11 | | // (See accompanying file LICENSE-Boost or copy at |
12 | | // https://www.boost.org/LICENSE_1_0.txt) |
13 | | // |
14 | | // Unless required by applicable law or agreed to in writing, this software |
15 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
16 | | // KIND, either express or implied. |
17 | | #ifndef RYU_COMMON_H |
18 | | #define RYU_COMMON_H |
19 | | |
20 | | #include <assert.h> |
21 | | #include <stdint.h> |
22 | | #include <string.h> |
23 | | |
24 | | #if defined(_M_IX86) || defined(_M_ARM) |
25 | | #define RYU_32_BIT_PLATFORM |
26 | | #endif |
27 | | |
28 | | // Returns the number of decimal digits in v, which must not contain more than 9 digits. |
29 | 0 | static inline uint32_t decimalLength9(const uint32_t v) { |
30 | 0 | // Function precondition: v is not a 10-digit number. |
31 | 0 | // (f2s: 9 digits are sufficient for round-tripping.) |
32 | 0 | // (d2fixed: We print 9-digit blocks.) |
33 | 0 | assert(v >= 0); |
34 | 0 | assert(v < 1000000000); |
35 | 0 | if (v >= 100000000) { return 9; } |
36 | 0 | if (v >= 10000000) { return 8; } |
37 | 0 | if (v >= 1000000) { return 7; } |
38 | 0 | if (v >= 100000) { return 6; } |
39 | 0 | if (v >= 10000) { return 5; } |
40 | 0 | if (v >= 1000) { return 4; } |
41 | 0 | if (v >= 100) { return 3; } |
42 | 0 | if (v >= 10) { return 2; } |
43 | 0 | return 1; |
44 | 0 | } |
45 | | |
46 | | // Returns e == 0 ? 1 : ceil(log_2(5^e)); requires 0 <= e <= 3528. |
47 | 0 | static inline int32_t pow5bits(const int32_t e) { |
48 | | // This approximation works up to the point that the multiplication overflows at e = 3529. |
49 | | // If the multiplication were done in 64 bits, it would fail at 5^4004 which is just greater |
50 | | // than 2^9297. |
51 | 0 | assert(e >= 0); |
52 | 0 | assert(e <= 3528); |
53 | 0 | return (int32_t) (((((uint32_t) e) * 1217359) >> 19) + 1); |
54 | 0 | } |
55 | | |
56 | | // Returns e == 0 ? 1 : ceil(log_2(5^e)); requires 0 <= e <= 3528. |
57 | 0 | static inline int32_t ceil_log2pow5(const int32_t e) { |
58 | 0 | return pow5bits(e); |
59 | 0 | } |
60 | | |
61 | | // Returns floor(log_10(2^e)); requires 0 <= e <= 1650. |
62 | 0 | static inline uint32_t log10Pow2(const int32_t e) { |
63 | | // The first value this approximation fails for is 2^1651 which is just greater than 10^297. |
64 | 0 | assert(e >= 0); |
65 | 0 | assert(e <= 1650); |
66 | 0 | return (((uint32_t) e) * 78913) >> 18; |
67 | 0 | } |
68 | | |
69 | | // Returns floor(log_10(5^e)); requires 0 <= e <= 2620. |
70 | 0 | static inline uint32_t log10Pow5(const int32_t e) { |
71 | | // The first value this approximation fails for is 5^2621 which is just greater than 10^1832. |
72 | 0 | assert(e >= 0); |
73 | 0 | assert(e <= 2620); |
74 | 0 | return (((uint32_t) e) * 732923) >> 20; |
75 | 0 | } |
76 | | |
77 | 0 | static inline int copy_special_str(char * const result, const bool sign, const bool exponent, const bool mantissa) { |
78 | 0 | if (mantissa) { |
79 | 0 | memcpy(result, "NaN", 3); |
80 | 0 | return 3; |
81 | 0 | } |
82 | 0 | if (exponent) { |
83 | | /* PostGIS: Do not print signed zero */ |
84 | 0 | if (sign) { |
85 | 0 | result[0] = '-'; |
86 | 0 | } |
87 | 0 | memcpy(result + sign, "Infinity", 8); |
88 | 0 | return sign + 8; |
89 | 0 | } |
90 | 0 | memcpy(result, "0", 1); |
91 | 0 | return 1; |
92 | 0 | } |
93 | | |
94 | 0 | static inline uint32_t float_to_bits(const float f) { |
95 | 0 | uint32_t bits = 0; |
96 | 0 | memcpy(&bits, &f, sizeof(float)); |
97 | 0 | return bits; |
98 | 0 | } |
99 | | |
100 | 0 | static inline uint64_t double_to_bits(const double d) { |
101 | 0 | uint64_t bits = 0; |
102 | 0 | memcpy(&bits, &d, sizeof(double)); |
103 | 0 | return bits; |
104 | 0 | } |
105 | | |
106 | | #endif // RYU_COMMON_H |