Age Owner Branch data TLA Line data Source code
1 : : /*---------------------------------------------------------------------------
2 : : *
3 : : * Common routines for Ryu floating-point output.
4 : : *
5 : : * Portions Copyright (c) 2018-2024, 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
1887 rhodiumtoad@postgres 54 :CBC 900643 : pow5bits(const int32 e)
55 : : {
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 [ - + ]: 900643 : Assert(e >= 0);
64 [ - + ]: 900643 : Assert(e <= 3528);
65 : 900643 : return ((((uint32) e) * 1217359) >> 19) + 1;
66 : : }
67 : :
68 : : /* Returns floor(log_10(2^e)). */
69 : : static inline int32
70 : 1602 : log10Pow2(const int32 e)
71 : : {
72 : : /*
73 : : * The first value this approximation fails for is 2^1651 which is just
74 : : * greater than 10^297.
75 : : */
76 [ - + ]: 1602 : Assert(e >= 0);
77 [ - + ]: 1602 : Assert(e <= 1650);
78 : 1602 : return (int32) ((((uint32) e) * 78913) >> 18);
79 : : }
80 : :
81 : : /* Returns floor(log_10(5^e)). */
82 : : static inline int32
83 : 897253 : log10Pow5(const int32 e)
84 : : {
85 : : /*
86 : : * The first value this approximation fails for is 5^2621 which is just
87 : : * greater than 10^1832.
88 : : */
89 [ - + ]: 897253 : Assert(e >= 0);
90 [ - + ]: 897253 : Assert(e <= 2620);
91 : 897253 : return (int32) ((((uint32) e) * 732923) >> 20);
92 : : }
93 : :
94 : : static inline int
95 : 9763 : copy_special_str(char *const result, const bool sign, const bool exponent, const bool mantissa)
96 : : {
97 [ + + ]: 9763 : if (mantissa)
98 : : {
99 : 242 : memcpy(result, "NaN", 3);
100 : 242 : return 3;
101 : : }
102 [ + + ]: 9521 : if (sign)
103 : : {
104 : 185 : result[0] = '-';
105 : : }
106 [ + + ]: 9521 : if (exponent)
107 : : {
108 : 449 : memcpy(result + sign, "Infinity", 8);
109 : 449 : return sign + 8;
110 : : }
111 : 9072 : result[sign] = '0';
112 : 9072 : return sign + 1;
113 : : }
114 : :
115 : : static inline uint32
116 : 25266 : float_to_bits(const float f)
117 : : {
118 : 25266 : uint32 bits = 0;
119 : :
120 : 25266 : memcpy(&bits, &f, sizeof(float));
121 : 25266 : return bits;
122 : : }
123 : :
124 : : static inline uint64
125 : 2077428 : double_to_bits(const double d)
126 : : {
127 : 2077428 : uint64 bits = 0;
128 : :
129 : 2077428 : memcpy(&bits, &d, sizeof(double));
130 : 2077428 : return bits;
131 : : }
132 : :
133 : : #endif /* RYU_COMMON_H */
|