PostgreSQL Source Code  git master
ryu_common.h
Go to the documentation of this file.
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
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  Assert(e >= 0);
64  Assert(e <= 3528);
65  return ((((uint32) e) * 1217359) >> 19) + 1;
66 }
67 
68 /* Returns floor(log_10(2^e)). */
69 static inline int32
71 {
72  /*
73  * The first value this approximation fails for is 2^1651 which is just
74  * greater than 10^297.
75  */
76  Assert(e >= 0);
77  Assert(e <= 1650);
78  return (int32) ((((uint32) e) * 78913) >> 18);
79 }
80 
81 /* Returns floor(log_10(5^e)). */
82 static inline int32
84 {
85  /*
86  * The first value this approximation fails for is 5^2621 which is just
87  * greater than 10^1832.
88  */
89  Assert(e >= 0);
90  Assert(e <= 2620);
91  return (int32) ((((uint32) e) * 732923) >> 20);
92 }
93 
94 static inline int
95 copy_special_str(char *const result, const bool sign, const bool exponent, const bool mantissa)
96 {
97  if (mantissa)
98  {
99  memcpy(result, "NaN", 3);
100  return 3;
101  }
102  if (sign)
103  {
104  result[0] = '-';
105  }
106  if (exponent)
107  {
108  memcpy(result + sign, "Infinity", 8);
109  return sign + 8;
110  }
111  result[sign] = '0';
112  return sign + 1;
113 }
114 
115 static inline uint32
116 float_to_bits(const float f)
117 {
118  uint32 bits = 0;
119 
120  memcpy(&bits, &f, sizeof(float));
121  return bits;
122 }
123 
124 static inline uint64
125 double_to_bits(const double d)
126 {
127  uint64 bits = 0;
128 
129  memcpy(&bits, &d, sizeof(double));
130  return bits;
131 }
132 
133 #endif /* RYU_COMMON_H */
unsigned int uint32
Definition: c.h:506
signed int int32
Definition: c.h:494
#define Assert(condition)
Definition: c.h:858
char sign
Definition: informix.c:674
e
Definition: preproc-init.c:82
static uint64 double_to_bits(const double d)
Definition: ryu_common.h:125
static uint32 float_to_bits(const float f)
Definition: ryu_common.h:116
static uint32 pow5bits(const int32 e)
Definition: ryu_common.h:54
static int32 log10Pow5(const int32 e)
Definition: ryu_common.h:83
static int copy_special_str(char *const result, const bool sign, const bool exponent, const bool mantissa)
Definition: ryu_common.h:95
static int32 log10Pow2(const int32 e)
Definition: ryu_common.h:70