LCOV - code coverage report
Current view: top level - src/util - serfloat.cpp (source / functions) Coverage Total Hit
Test: test_bitcoin_coverage.info Lines: 100.0 % 31 31
Test Date: 2024-11-04 04:45:35 Functions: 100.0 % 2 2
Branches: 92.3 % 26 24

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2021 The Bitcoin Core developers
       2                 :             : // Distributed under the MIT software license, see the accompanying
       3                 :             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4                 :             : 
       5                 :             : #include <util/serfloat.h>
       6                 :             : 
       7                 :             : #include <cmath>
       8                 :             : #include <limits>
       9                 :             : 
      10                 :      513058 : double DecodeDouble(uint64_t v) noexcept {
      11                 :      513058 :     static constexpr double NANVAL = std::numeric_limits<double>::quiet_NaN();
      12                 :      513058 :     static constexpr double INFVAL = std::numeric_limits<double>::infinity();
      13                 :      513058 :     double sign = 1.0;
      14         [ +  + ]:      513058 :     if (v & 0x8000000000000000) {
      15                 :      255910 :         sign = -1.0;
      16                 :      255910 :         v ^= 0x8000000000000000;
      17                 :             :     }
      18                 :             :     // Zero
      19         [ +  + ]:      513058 :     if (v == 0) return copysign(0.0, sign);
      20                 :             :     // Infinity
      21         [ +  + ]:      513055 :     if (v == 0x7ff0000000000000) return copysign(INFVAL, sign);
      22                 :             :     // Other numbers
      23                 :      513053 :     int exp = (v & 0x7FF0000000000000) >> 52;
      24                 :      513053 :     uint64_t man = v & 0xFFFFFFFFFFFFF;
      25         [ +  + ]:      513053 :     if (exp == 2047) {
      26                 :             :         // NaN
      27                 :             :         return NANVAL;
      28         [ +  + ]:      512804 :     } else if (exp == 0) {
      29                 :             :         // Subnormal
      30                 :         256 :         return copysign(ldexp((double)man, -1074), sign);
      31                 :             :     } else {
      32                 :             :         // Normal
      33                 :      512548 :         return copysign(ldexp((double)(man + 0x10000000000000), -1075 + exp), sign);
      34                 :             :     }
      35                 :             : }
      36                 :             : 
      37                 :     1024867 : uint64_t EncodeDouble(double f) noexcept {
      38         [ +  + ]:     1024867 :     int cls = std::fpclassify(f);
      39                 :     1024867 :     uint64_t sign = 0;
      40         [ +  + ]:     1024867 :     if (copysign(1.0, f) == -1.0) {
      41                 :      511935 :         f = -f;
      42                 :      511935 :         sign = 0x8000000000000000;
      43                 :             :     }
      44                 :             :     // Zero
      45         [ +  + ]:     1024867 :     if (cls == FP_ZERO) return sign;
      46                 :             :     // Infinity
      47         [ +  + ]:     1024862 :     if (cls == FP_INFINITE) return sign | 0x7ff0000000000000;
      48                 :             :     // NaN
      49         [ +  + ]:     1024858 :     if (cls == FP_NAN) return 0x7ff8000000000000;
      50                 :             :     // Other numbers
      51                 :     1024609 :     int exp;
      52                 :     1024609 :     uint64_t man = std::round(std::frexp(f, &exp) * 9007199254740992.0);
      53         [ +  + ]:     1024609 :     if (exp < -1021) {
      54                 :             :         // Too small to represent, encode 0
      55         [ +  - ]:         512 :         if (exp < -1084) return sign;
      56                 :             :         // Subnormal numbers
      57                 :         512 :         return sign | (man >> (-1021 - exp));
      58                 :             :     } else {
      59                 :             :         // Too big to represent, encode infinity
      60         [ -  + ]:     1024097 :         if (exp > 1024) return sign | 0x7ff0000000000000;
      61                 :             :         // Normal numbers
      62                 :     1024097 :         return sign | (((uint64_t)(1022 + exp)) << 52) | (man & 0xFFFFFFFFFFFFF);
      63                 :             :     }
      64                 :             : }
        

Generated by: LCOV version 2.0-1