LCOV - code coverage report
Current view: top level - src/common - ryu_common.h (source / functions) Hit Total Coverage
Test: PostgreSQL 17devel Lines: 25 25 100.0 %
Date: 2024-04-24 23:13:15 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          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     3198504 : 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     3198504 :     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     3191700 : 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     3191700 :     return (int32) ((((uint32) e) * 732923) >> 20);
      92             : }
      93             : 
      94             : static inline int
      95      718784 : copy_special_str(char *const result, const bool sign, const bool exponent, const bool mantissa)
      96             : {
      97      718784 :     if (mantissa)
      98             :     {
      99         494 :         memcpy(result, "NaN", 3);
     100         494 :         return 3;
     101             :     }
     102      718290 :     if (sign)
     103             :     {
     104         386 :         result[0] = '-';
     105             :     }
     106      718290 :     if (exponent)
     107             :     {
     108         930 :         memcpy(result + sign, "Infinity", 8);
     109         930 :         return sign + 8;
     110             :     }
     111      717360 :     result[sign] = '0';
     112      717360 :     return sign + 1;
     113             : }
     114             : 
     115             : static inline uint32
     116       49786 : float_to_bits(const float f)
     117             : {
     118       49786 :     uint32      bits = 0;
     119             : 
     120       49786 :     memcpy(&bits, &f, sizeof(float));
     121       49786 :     return bits;
     122             : }
     123             : 
     124             : static inline uint64
     125     7237586 : double_to_bits(const double d)
     126             : {
     127     7237586 :     uint64      bits = 0;
     128             : 
     129     7237586 :     memcpy(&bits, &d, sizeof(double));
     130     7237586 :     return bits;
     131             : }
     132             : 
     133             : #endif                          /* RYU_COMMON_H */

Generated by: LCOV version 1.14