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 54 3473646 : 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 : Assert(e >= 0); 64 : Assert(e <= 3528); 65 3473646 : return ((((uint32) e) * 1217359) >> 19) + 1; 66 : } 67 : 68 : /* Returns floor(log_10(2^e)). */ 69 : static inline int32 70 3204 : 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 : Assert(e >= 0); 77 : Assert(e <= 1650); 78 3204 : return (int32) ((((uint32) e) * 78913) >> 18); 79 : } 80 : 81 : /* Returns floor(log_10(5^e)). */ 82 : static inline int32 83 3460074 : 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 : Assert(e >= 0); 90 : Assert(e <= 2620); 91 3460074 : return (int32) ((((uint32) e) * 732923) >> 20); 92 : } 93 : 94 : static inline int 95 760068 : copy_special_str(char *const result, const bool sign, const bool exponent, const bool mantissa) 96 : { 97 760068 : if (mantissa) 98 : { 99 494 : memcpy(result, "NaN", 3); 100 494 : return 3; 101 : } 102 759574 : if (sign) 103 : { 104 386 : result[0] = '-'; 105 : } 106 759574 : if (exponent) 107 : { 108 998 : memcpy(result + sign, "Infinity", 8); 109 998 : return sign + 8; 110 : } 111 758576 : result[sign] = '0'; 112 758576 : return sign + 1; 113 : } 114 : 115 : static inline uint32 116 155858 : float_to_bits(const float f) 117 : { 118 155858 : uint32 bits = 0; 119 : 120 155858 : memcpy(&bits, &f, sizeof(float)); 121 155858 : return bits; 122 : } 123 : 124 : static inline uint64 125 7501928 : double_to_bits(const double d) 126 : { 127 7501928 : uint64 bits = 0; 128 : 129 7501928 : memcpy(&bits, &d, sizeof(double)); 130 7501928 : return bits; 131 : } 132 : 133 : #endif /* RYU_COMMON_H */