Coverage Report

Created: 2025-06-13 06:06

/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 */