Bitcoin Core 28.99.0
P2P Digital Currency
serfloat.cpp
Go to the documentation of this file.
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
10double DecodeDouble(uint64_t v) noexcept {
11 static constexpr double NANVAL = std::numeric_limits<double>::quiet_NaN();
12 static constexpr double INFVAL = std::numeric_limits<double>::infinity();
13 double sign = 1.0;
14 if (v & 0x8000000000000000) {
15 sign = -1.0;
16 v ^= 0x8000000000000000;
17 }
18 // Zero
19 if (v == 0) return copysign(0.0, sign);
20 // Infinity
21 if (v == 0x7ff0000000000000) return copysign(INFVAL, sign);
22 // Other numbers
23 int exp = (v & 0x7FF0000000000000) >> 52;
24 uint64_t man = v & 0xFFFFFFFFFFFFF;
25 if (exp == 2047) {
26 // NaN
27 return NANVAL;
28 } else if (exp == 0) {
29 // Subnormal
30 return copysign(ldexp((double)man, -1074), sign);
31 } else {
32 // Normal
33 return copysign(ldexp((double)(man + 0x10000000000000), -1075 + exp), sign);
34 }
35}
36
37uint64_t EncodeDouble(double f) noexcept {
38 int cls = std::fpclassify(f);
39 uint64_t sign = 0;
40 if (copysign(1.0, f) == -1.0) {
41 f = -f;
42 sign = 0x8000000000000000;
43 }
44 // Zero
45 if (cls == FP_ZERO) return sign;
46 // Infinity
47 if (cls == FP_INFINITE) return sign | 0x7ff0000000000000;
48 // NaN
49 if (cls == FP_NAN) return 0x7ff8000000000000;
50 // Other numbers
51 int exp;
52 uint64_t man = std::round(std::frexp(f, &exp) * 9007199254740992.0);
53 if (exp < -1021) {
54 // Too small to represent, encode 0
55 if (exp < -1084) return sign;
56 // Subnormal numbers
57 return sign | (man >> (-1021 - exp));
58 } else {
59 // Too big to represent, encode infinity
60 if (exp > 1024) return sign | 0x7ff0000000000000;
61 // Normal numbers
62 return sign | (((uint64_t)(1022 + exp)) << 52) | (man & 0xFFFFFFFFFFFFF);
63 }
64}
static int sign(const secp256k1_context *ctx, struct signer_secrets *signer_secrets, struct signer *signer, const secp256k1_musig_keyagg_cache *cache, const unsigned char *msg32, unsigned char *sig64)
Definition: musig.c:105
uint64_t EncodeDouble(double f) noexcept
Definition: serfloat.cpp:37
double DecodeDouble(uint64_t v) noexcept
Definition: serfloat.cpp:10