Inside Bitcoin
Opening the selected file…
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2021-present The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#include <util/serfloat.h>7#include <cmath>8#include <limits>10double DecodeDouble(uint64_t v) noexcept {11static constexpr double NANVAL = std::numeric_limits<double>::quiet_NaN();12static constexpr double INFVAL = std::numeric_limits<double>::infinity();13double sign = 1.0;14if (v & 0x8000000000000000) {15sign = -1.0;16v ^= 0x8000000000000000;17}18// Zero19if (v == 0) return copysign(0.0, sign);20// Infinity21if (v == 0x7ff0000000000000) return copysign(INFVAL, sign);22// Other numbers23int exp = (v & 0x7FF0000000000000) >> 52;24uint64_t man = v & 0xFFFFFFFFFFFFF;25if (exp == 2047) {26// NaN27return NANVAL;28} else if (exp == 0) {29// Subnormal30return copysign(ldexp((double)man, -1074), sign);31} else {32// Normal33return copysign(ldexp((double)(man + 0x10000000000000), -1075 + exp), sign);34}35}37uint64_t EncodeDouble(double f) noexcept {38int cls = std::fpclassify(f);39uint64_t sign = 0;40if (copysign(1.0, f) == -1.0) {41f = -f;42sign = 0x8000000000000000;43}44// Zero45if (cls == FP_ZERO) return sign;46// Infinity47if (cls == FP_INFINITE) return sign | 0x7ff0000000000000;48// NaN49if (cls == FP_NAN) return 0x7ff8000000000000;50// Other numbers51int exp;52uint64_t man = std::round(std::frexp(f, &exp) * 9007199254740992.0);53if (exp < -1021) {54// Too small to represent, encode 055if (exp < -1084) return sign;56// Subnormal numbers57return sign | (man >> (-1021 - exp));58} else {59// Too big to represent, encode infinity60if (exp > 1024) return sign | 0x7ff0000000000000;61// Normal numbers62return sign | (((uint64_t)(1022 + exp)) << 52) | (man & 0xFFFFFFFFFFFFF);63}64}