/src/postgres/src/common/ryu_common.h
Line | Count | Source (jump to first uncovered line) |
1 | | /*--------------------------------------------------------------------------- |
2 | | * |
3 | | * Common routines for Ryu floating-point output. |
4 | | * |
5 | | * Portions Copyright (c) 2018-2025, PostgreSQL Global Development Group |
6 | | * |
7 | | * IDENTIFICATION |
8 | | * src/common/ryu_common.h |
9 | | * |
10 | | * This is a modification of code taken from github.com/ulfjack/ryu under the |
11 | | * terms of the Boost license (not the Apache license). The original copyright |
12 | | * notice follows: |
13 | | * |
14 | | * Copyright 2018 Ulf Adams |
15 | | * |
16 | | * The contents of this file may be used under the terms of the Apache |
17 | | * License, Version 2.0. |
18 | | * |
19 | | * (See accompanying file LICENSE-Apache or copy at |
20 | | * http://www.apache.org/licenses/LICENSE-2.0) |
21 | | * |
22 | | * Alternatively, the contents of this file may be used under the terms of the |
23 | | * Boost Software License, Version 1.0. |
24 | | * |
25 | | * (See accompanying file LICENSE-Boost or copy at |
26 | | * https://www.boost.org/LICENSE_1_0.txt) |
27 | | * |
28 | | * Unless required by applicable law or agreed to in writing, this software is |
29 | | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
30 | | * KIND, either express or implied. |
31 | | * |
32 | | *--------------------------------------------------------------------------- |
33 | | */ |
34 | | #ifndef RYU_COMMON_H |
35 | | #define RYU_COMMON_H |
36 | | |
37 | | /* |
38 | | * Upstream Ryu's output is always the shortest possible. But we adjust that |
39 | | * slightly to improve portability: we avoid outputting the exact midpoint |
40 | | * value between two representable floats, since that relies on the reader |
41 | | * getting the round-to-even rule correct, which seems to be the common |
42 | | * failure mode. |
43 | | * |
44 | | * Defining this to 1 would restore the upstream behavior. |
45 | | */ |
46 | | #define STRICTLY_SHORTEST 0 |
47 | | |
48 | | #if SIZEOF_SIZE_T < 8 |
49 | | #define RYU_32_BIT_PLATFORM |
50 | | #endif |
51 | | |
52 | | /* Returns e == 0 ? 1 : ceil(log_2(5^e)). */ |
53 | | static inline uint32 |
54 | | pow5bits(const int32 e) |
55 | 0 | { |
56 | | /* |
57 | | * This approximation works up to the point that the multiplication |
58 | | * overflows at e = 3529. |
59 | | * |
60 | | * If the multiplication were done in 64 bits, it would fail at 5^4004 |
61 | | * which is just greater than 2^9297. |
62 | | */ |
63 | 0 | Assert(e >= 0); |
64 | 0 | Assert(e <= 3528); |
65 | 0 | return ((((uint32) e) * 1217359) >> 19) + 1; |
66 | 0 | } Unexecuted instantiation: d2s.c:pow5bits Unexecuted instantiation: f2s.c:pow5bits |
67 | | |
68 | | /* Returns floor(log_10(2^e)). */ |
69 | | static inline int32 |
70 | | log10Pow2(const int32 e) |
71 | 0 | { |
72 | | /* |
73 | | * The first value this approximation fails for is 2^1651 which is just |
74 | | * greater than 10^297. |
75 | | */ |
76 | 0 | Assert(e >= 0); |
77 | 0 | Assert(e <= 1650); |
78 | 0 | return (int32) ((((uint32) e) * 78913) >> 18); |
79 | 0 | } Unexecuted instantiation: d2s.c:log10Pow2 Unexecuted instantiation: f2s.c:log10Pow2 |
80 | | |
81 | | /* Returns floor(log_10(5^e)). */ |
82 | | static inline int32 |
83 | | log10Pow5(const int32 e) |
84 | 0 | { |
85 | | /* |
86 | | * The first value this approximation fails for is 5^2621 which is just |
87 | | * greater than 10^1832. |
88 | | */ |
89 | 0 | Assert(e >= 0); |
90 | 0 | Assert(e <= 2620); |
91 | 0 | return (int32) ((((uint32) e) * 732923) >> 20); |
92 | 0 | } Unexecuted instantiation: d2s.c:log10Pow5 Unexecuted instantiation: f2s.c:log10Pow5 |
93 | | |
94 | | static inline int |
95 | | copy_special_str(char *const result, const bool sign, const bool exponent, const bool mantissa) |
96 | 0 | { |
97 | 0 | if (mantissa) |
98 | 0 | { |
99 | 0 | memcpy(result, "NaN", 3); |
100 | 0 | return 3; |
101 | 0 | } |
102 | 0 | if (sign) |
103 | 0 | { |
104 | 0 | result[0] = '-'; |
105 | 0 | } |
106 | 0 | if (exponent) |
107 | 0 | { |
108 | 0 | memcpy(result + sign, "Infinity", 8); |
109 | 0 | return sign + 8; |
110 | 0 | } |
111 | 0 | result[sign] = '0'; |
112 | 0 | return sign + 1; |
113 | 0 | } Unexecuted instantiation: d2s.c:copy_special_str Unexecuted instantiation: f2s.c:copy_special_str |
114 | | |
115 | | static inline uint32 |
116 | | float_to_bits(const float f) |
117 | 0 | { |
118 | 0 | uint32 bits = 0; |
119 | |
|
120 | 0 | memcpy(&bits, &f, sizeof(float)); |
121 | 0 | return bits; |
122 | 0 | } Unexecuted instantiation: d2s.c:float_to_bits Unexecuted instantiation: f2s.c:float_to_bits |
123 | | |
124 | | static inline uint64 |
125 | | double_to_bits(const double d) |
126 | 0 | { |
127 | 0 | uint64 bits = 0; |
128 | |
|
129 | 0 | memcpy(&bits, &d, sizeof(double)); |
130 | 0 | return bits; |
131 | 0 | } Unexecuted instantiation: d2s.c:double_to_bits Unexecuted instantiation: f2s.c:double_to_bits |
132 | | |
133 | | #endif /* RYU_COMMON_H */ |