Coverage Report

Created: 2026-04-20 22:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/root/bitcoin/src/util/serfloat.cpp
Line
Count
Source
1
// Copyright (c) 2021-present 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
736k
double DecodeDouble(uint64_t v) noexcept {
11
736k
    static constexpr double NANVAL = std::numeric_limits<double>::quiet_NaN();
12
736k
    static constexpr double INFVAL = std::numeric_limits<double>::infinity();
13
736k
    double sign = 1.0;
14
736k
    if (v & 0x8000000000000000) {
15
117k
        sign = -1.0;
16
117k
        v ^= 0x8000000000000000;
17
117k
    }
18
    // Zero
19
736k
    if (v == 0) return copysign(0.0, sign);
20
    // Infinity
21
531k
    if (v == 0x7ff0000000000000) return copysign(INFVAL, sign);
22
    // Other numbers
23
531k
    int exp = (v & 0x7FF0000000000000) >> 52;
24
531k
    uint64_t man = v & 0xFFFFFFFFFFFFF;
25
531k
    if (exp == 2047) {
26
        // NaN
27
6.78k
        return NANVAL;
28
524k
    } else if (exp == 0) {
29
        // Subnormal
30
24.9k
        return copysign(ldexp((double)man, -1074), sign);
31
499k
    } else {
32
        // Normal
33
499k
        return copysign(ldexp((double)(man + 0x10000000000000), -1075 + exp), sign);
34
499k
    }
35
531k
}
36
37
744k
uint64_t EncodeDouble(double f) noexcept {
38
744k
    int cls = std::fpclassify(f);
39
744k
    uint64_t sign = 0;
40
744k
    if (copysign(1.0, f) == -1.0) {
41
220
        f = -f;
42
220
        sign = 0x8000000000000000;
43
220
    }
44
    // Zero
45
744k
    if (cls == FP_ZERO) return sign;
46
    // Infinity
47
39.7k
    if (cls == FP_INFINITE) return sign | 0x7ff0000000000000;
48
    // NaN
49
39.7k
    if (cls == FP_NAN) return 0x7ff8000000000000;
50
    // Other numbers
51
39.6k
    int exp;
52
39.6k
    uint64_t man = std::round(std::frexp(f, &exp) * 9007199254740992.0);
53
39.6k
    if (exp < -1021) {
54
        // Too small to represent, encode 0
55
326
        if (exp < -1084) return sign;
56
        // Subnormal numbers
57
326
        return sign | (man >> (-1021 - exp));
58
39.3k
    } else {
59
        // Too big to represent, encode infinity
60
39.3k
        if (exp > 1024) return sign | 0x7ff0000000000000;
61
        // Normal numbers
62
39.3k
        return sign | (((uint64_t)(1022 + exp)) << 52) | (man & 0xFFFFFFFFFFFFF);
63
39.3k
    }
64
39.6k
}