fuzz coverage

Coverage Report

Created: 2025-06-01 19:34

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