Float — 多倍長浮動小数点
概要
Float は calx の任意精度浮動小数点型である。
内部表現は (符号, 仮数部 Int, 指数部 int64_t) の 3 つ組で、
値 $x$ を次のように表す。
ここで $s$ は符号ビット、$m$ は多倍長整数(Int)の仮数部、$e$ は 64 ビット整数の指数部である。
精度は 10 進桁数で指定し、内部ではビット精度に変換される。
IEEE 754 に準じた丸めモード(RoundingMode)をサポートし、
NaN および Infinity は全演算で安全に伝播する。
- 任意精度 — 桁数に制限なし。数十万桁の計算が可能
- NaN/Infinity 安全 — 特殊値は IEEE 754 と同様のセマンティクスで伝播
- thread_local 定数キャッシュ — $\pi, e, \log 2$ 等の数学定数はスレッドごとにキャッシュされ、同一精度での再計算を回避
- 精度追跡 — 有効ビット数(
effectiveBits)と要求ビット数(requestedBits)を自動管理
ビルド
必要なヘッダ
#include <math/core/mp/Float.hpp> // Float クラス本体
#include <math/core/mp/Float/FloatMath.hpp> // cbrt, nthRoot, fma, fmma, sqr, logUi 等
リンクするライブラリ: calx_float(calx_int に依存)。
コンストラクタ
| シグネチャ | 説明 |
|---|---|
Float() | デフォルト構築。値は 0 |
Float(int value) | int から構築 |
Float(int64_t value) | 64 ビット整数から構築 |
Float(double value) | double から構築(53 ビット精度) |
Float(std::string_view str) | 文字列から構築(10 進) |
Float(const Int& value) | 多倍長整数から構築(exact) |
Float(const Int& mantissa, int64_t exponent, bool is_negative = false) | 仮数部 + 指数部から構築 |
Float(Int&& mantissa, int64_t exponent, bool is_negative = false) | 仮数部(ムーブ)+ 指数部から構築 |
Float(int64_t mantissa, int64_t exponent, bool is_negative = false) | 整数仮数部 + 指数部から構築 |
コピー・ムーブコンストラクタおよび代入演算子はすべて default で提供される。
int64_t と double からの代入演算子も利用可能。
特殊値ファクトリ
すべて static メンバ関数である。
| シグネチャ | 説明 |
|---|---|
Float positiveInfinity() | $+\infty$ を返す |
Float negativeInfinity() | $-\infty$ を返す |
Float nan() | NaN を返す |
Float epsilon(int precision) | 指定精度での機械イプシロン |
Float zero(int precision) | 指定精度のゼロ |
Float one(int precision) | 指定精度の 1 |
precision を省略すると defaultPrecision()(スレッドローカル)が使用される。
数学定数
すべて static メンバ関数で、thread_local キャッシュにより同一精度での再計算を回避する。
| シグネチャ | 説明 | アルゴリズム |
|---|---|---|
Float pi(int precision) | 円周率 $\pi \approx 3.1416$ | Chudnovsky (binary splitting) |
Float e(int precision) | 自然対数の底 $e \approx 2.7183$ | $\sum 1/n!$ (binary splitting) |
Float log2(int precision) | $\ln 2 \approx 0.6931$ | atanh 系列 |
Float log10(int precision) | $\ln 10 \approx 2.3026$ | atanh 系列 |
Float euler(int precision) | Euler-Mascheroni 定数 $\gamma \approx 0.5772$ | Brent-McMillan |
Float catalan(int precision) | Catalan 定数 $G \approx 0.9160$ | Euler 級数 |
三角・円定数
| シグネチャ | 説明 |
|---|---|
Float::half_pi(int precision) | $\pi/2 \approx 1.5708$ |
Float::quarter_pi(int precision) | $\pi/4 \approx 0.7854$ |
Float::two_pi(int precision) | $2\pi \approx 6.2832$ |
Float::inv_pi(int precision) | $1/\pi \approx 0.3183$ |
Float::two_inv_pi(int precision) | $2/\pi \approx 0.6366$ |
Float::pi_squared_over_6(int precision) | $\pi^2/6 = \zeta(2) \approx 1.6449$ |
Float::pi_squared_over_12(int precision) | $\pi^2/12 \approx 0.8225$ |
Float::inv_sqrt_pi(int precision) | $1/\sqrt{\pi} \approx 0.5642$ |
Float::two_inv_sqrt_pi(int precision) | $2/\sqrt{\pi} \approx 1.1284$ |
Float::degree(int precision) | $\pi/180 \approx 0.01745$ |
根号定数
| シグネチャ | 説明 |
|---|---|
Float::sqrt2(int precision) | $\sqrt{2} \approx 1.4142$ |
Float::sqrt3(int precision) | $\sqrt{3} \approx 1.7321$ |
Float::sqrt5(int precision) | $\sqrt{5} \approx 2.2361$ |
Float::inv_sqrt2(int precision) | $1/\sqrt{2} \approx 0.7071$ |
Float::cbrt2(int precision) | $\sqrt[3]{2} \approx 1.2599$ |
対数定数
| シグネチャ | 説明 |
|---|---|
Float::ln3(int precision) | $\ln 3 \approx 1.0986$ |
Float::ln5(int precision) | $\ln 5 \approx 1.6094$ |
Float::log2e(int precision) | $\log_2 e \approx 1.4427$ |
Float::log10e(int precision) | $\log_{10} e \approx 0.4343$ |
著名な定数
| シグネチャ | 説明 |
|---|---|
Float::phi(int precision) | 黄金比 $(1+\sqrt{5})/2 \approx 1.6180$ |
Float::lemniscate(int precision) | レムニスケート定数 $\varpi \approx 2.6221$ |
Float::gamma14(int precision) | $\Gamma(1/4) \approx 3.6256$ |
Float::zeta3(int precision) | Apéry 定数 $\zeta(3) \approx 1.2021$ |
Float::zeta5(int precision) | $\zeta(5) \approx 1.0369$ |
Float::zeta7(int precision) | $\zeta(7) \approx 1.0083$ |
Float::glaisher(int precision) | Glaisher-Kinkelin 定数 $A \approx 1.2824$ |
Float::khinchin(int precision) | Khinchin 定数 $K \approx 2.6854$ |
Float::omega(int precision) | $\Omega$ (Lambert $W(1)$) $\approx 0.5671$ |
Float::sin1(int precision) | $\sin 1 \approx 0.8415$ |
Float::cos1(int precision) | $\cos 1 \approx 0.5403$ |
希少な数学定数
| シグネチャ | 説明 |
|---|---|
Float::plastic(int precision) | プラスチック数 $\approx 1.3247$ |
Float::twin_prime(int precision) | 双子素数定数 $C_2 \approx 0.6602$ |
Float::landau_ramanujan(int precision) | Landau-Ramanujan 定数 $\approx 0.7642$ |
Float::meissel_mertens(int precision) | Meissel-Mertens 定数 $\approx 0.2615$ |
Float::bernstein(int precision) | Bernstein 定数 $\approx 0.2801$ |
Float::gauss_kuzmin(int precision) | Gauss-Kuzmin-Wirsing 定数 $\approx 0.3037$ |
Float::feigenbaum_delta(int precision) | Feigenbaum $\delta \approx 4.6692$ |
Float::feigenbaum_alpha(int precision) | Feigenbaum $\alpha \approx 2.5029$ |
Float::erdos_borwein(int precision) | Erdős-Borwein 定数 $\approx 1.6066$ |
Float::laplace_limit(int precision) | Laplace limit 定数 $\approx 0.6627$ |
Float::soldner(int precision) | Ramanujan-Soldner 定数 $\mu \approx 1.4513$ |
Float::backhouse(int precision) | Backhouse 定数 $\approx 1.4560$ |
Float::porter(int precision) | Porter 定数 $\approx 1.4670$ |
Float::lieb_square_ice(int precision) | Lieb の square ice 定数 $\approx 1.5396$ |
Float::niven(int precision) | Niven 定数 $\approx 1.7052$ |
Float::reciprocal_fibonacci(int precision) | 逆 Fibonacci 定数 $\approx 3.3599$ |
Float::sierpinski(int precision) | Sierpiński 定数 $\approx 2.5849$ |
Float::mills(int precision) | Mills 定数 $\approx 1.3064$ |
Float::dottie(int precision) | Dottie 数 $\approx 0.7391$ |
Float::golomb_dickman(int precision) | Golomb-Dickman 定数 $\approx 0.6243$ |
Float::salem(int precision) | Salem 定数 $\approx 1.1762$ |
Float::cahen(int precision) | Cahen 定数 $\approx 0.6434$ |
Float::levy(int precision) | Lévy 定数 $\approx 3.2758$ |
Float::copeland_erdos(int precision) | Copeland-Erdős 定数 $\approx 0.2357$ |
Float::egamma_exp(int precision) | $e^{\gamma} \approx 1.7811$ |
精度制御
| シグネチャ | 説明 |
|---|---|
Float& setPrecision(int precision) | 有効桁数を設定(丸め処理あり)。自身への参照を返す |
int precision() const | 現在の有効桁数を取得 |
int effectiveBits() const | 信頼できるビット数を取得 |
int requestedBits() const | 目標ビット数を取得 |
void truncateToApprox(int precision) | ワード単位の高速近似切り詰め(中間計算用) |
static int precisionToBits(int precision) | 10 進桁数 → ビット数 |
static int bitsToPrecision(int bits) | ビット数 → 10 進桁数 |
static int defaultPrecision() | スレッドローカルのデフォルト精度を取得 |
static void setDefaultPrecision(int precision) | スレッドローカルのデフォルト精度を設定 |
丸めモード
enum class RoundingMode {
ToNearest, // 最も近い値に丸め(デフォルト)
TowardZero, // ゼロ方向に丸め(切り捨て)
TowardPositive, // 正の無限大方向に丸め(切り上げ)
TowardNegative, // 負の無限大方向に丸め(切り下げ)
AwayFromZero // ゼロから遠ざかる方向に丸め
};
| シグネチャ | 説明 |
|---|---|
static RoundingMode roundingMode() | 現在の丸めモードを取得 |
static void setRoundingMode(RoundingMode mode) | 丸めモードを設定 |
状態確認
| シグネチャ | 説明 |
|---|---|
bool isNaN() const | NaN なら true |
bool isInfinity() const | $\pm\infty$ なら true |
bool isZero() const | ゼロなら true |
bool isNegative() const | 負なら true |
bool isPositive() const | 非負なら true(!isNegative()) |
bool isExact() const | 整数由来の正確な値なら true |
bool isInteger() const | 整数値なら true(NaN/Infinity は false) |
bool fitsInt() const | int 範囲に収まるか |
bool fitsInt64() const | int64_t 範囲に収まるか |
bool fitsDouble() const | double 範囲に収まるか |
算術演算子
| シグネチャ | 説明 |
|---|---|
Float operator+(const Float&, const Float&) | 加算 |
Float operator-(const Float&, const Float&) | 減算 |
Float operator*(const Float&, const Float&) | 乗算 |
Float operator/(const Float&, const Float&) | 除算 |
Float operator/(const Float&, int64_t) | 整数除算(高速パス) |
Float& operator+=(const Float&) | 加算代入 |
Float& operator-=(const Float&) | 減算代入 |
Float& operator*=(const Float&) | 乗算代入 |
Float& operator/=(const Float&) | 除算代入 |
Float operator-(const Float&) | 単項マイナス(符号反転) |
Float operator<<(const Float&, int) | 左シフト($\times 2^n$) |
Float operator>>(const Float&, int) | 右シフト($\div 2^n$) |
精度伝播ポリシー(デフォルト: MAX_PROPAGATION)に基づき、
結果の requestedBits は max(lhs, rhs)、
effectiveBits は min(lhs, rhs) となる。
比較演算子
| シグネチャ | 説明 |
|---|---|
bool operator==(const Float&, const Float&) | 等価比較 |
std::partial_ordering operator<=>(const Float&, const Float&) | 三方比較(C++20) |
三方比較演算子により !=, <, >, <=, >= が自動生成される。
NaN が含まれる比較はすべて std::partial_ordering::unordered を返す(IEEE 754 準拠)。
基本数学関数
すべて calx 名前空間のフリー関数である。
precision 引数は 10 進桁数で、計算の作業精度を指定する。
ムーブ版オーバーロードも提供されるが、表では省略する。
指数・対数
| シグネチャ | 説明 |
|---|---|
Float exp(const Float& x, int precision) | $e^x$ |
Float exp2(const Float& x, int precision) | $2^x$ |
Float exp10(const Float& x, int precision) | $10^x$ |
Float expm1(const Float& x, int precision) | $e^x - 1$($x \approx 0$ で高精度) |
Float log(const Float& x, int precision) | $\ln x$(AGM 法) |
Float log2(const Float& x, int precision) | $\log_2 x$ |
Float log10(const Float& x, int precision) | $\log_{10} x$ |
Float log1p(const Float& x, int precision) | $\ln(1+x)$($x \approx 0$ で高精度) |
Float logUi(unsigned long long n, int precision) | 整数の対数(素因数分解経由で高精度) |
三角関数
| シグネチャ | 説明 |
|---|---|
Float sin(const Float& x, int precision) | $\sin x$ |
Float cos(const Float& x, int precision) | $\cos x$ |
Float tan(const Float& x, int precision) | $\tan x$ |
Float sinPi(const Float& x, int precision) | $\sin(\pi x)$(整数点で正確に 0) |
Float cosPi(const Float& x, int precision) | $\cos(\pi x)$ |
Float tanPi(const Float& x, int precision) | $\tan(\pi x)$ |
Float sec(const Float& x, int precision) | $\sec x = 1/\cos x$ |
Float csc(const Float& x, int precision) | $\csc x = 1/\sin x$ |
Float cot(const Float& x, int precision) | $\cot x = \cos x/\sin x$ |
逆三角関数
| シグネチャ | 説明 |
|---|---|
Float asin(const Float& x, int precision) | $\arcsin x$ |
Float acos(const Float& x, int precision) | $\arccos x$ |
Float atan(const Float& x, int precision) | $\arctan x$(Taylor + 引数半減) |
Float atan2(const Float& y, const Float& x, int precision) | $\mathrm{atan2}(y, x)$ |
Float asinPi(const Float& x, int precision) | $\arcsin(x) / \pi$ |
Float acosPi(const Float& x, int precision) | $\arccos(x) / \pi$ |
Float atanPi(const Float& x, int precision) | $\arctan(x) / \pi$ |
双曲線関数
| シグネチャ | 説明 |
|---|---|
Float sinh(const Float& x, int precision) | $\sinh x$ |
Float cosh(const Float& x, int precision) | $\cosh x$ |
Float tanh(const Float& x, int precision) | $\tanh x$ |
Float sech(const Float& x, int precision) | $\mathrm{sech}\,x = 1/\cosh x$ |
Float csch(const Float& x, int precision) | $\mathrm{csch}\,x = 1/\sinh x$ |
Float coth(const Float& x, int precision) | $\coth x = \cosh x/\sinh x$ |
逆双曲線関数
| シグネチャ | 説明 |
|---|---|
Float asinh(const Float& x, int precision) | $\mathrm{arcsinh}\,x$ |
Float acosh(const Float& x, int precision) | $\mathrm{arccosh}\,x$ |
Float atanh(const Float& x, int precision) | $\mathrm{arctanh}\,x$ |
冪乗・根
| シグネチャ | 説明 |
|---|---|
Float sqr(const Float& x, int precision) | $x^2$(二乗、最適化アルゴリズム使用) |
Float pow(const Float& x, const Float& y, int precision) | $x^y$ |
Float pow(const Float& x, int n, int precision) | $x^n$(整数冪、二分累乗法) |
Float sqrt(const Float& x, int precision) | $\sqrt{x}$ |
Float cbrt(const Float& x, int precision) | $\sqrt[3]{x}$ |
Float nthRoot(const Float& x, int n, int precision) | $\sqrt[n]{x}$ |
Float recSqrt(const Float& x, int precision) | $1/\sqrt{x}$(逆平方根) |
Float hypot(const Float& x, const Float& y, int precision) | $\sqrt{x^2 + y^2}$(オーバーフロー安全) |
その他
| シグネチャ | 説明 |
|---|---|
Float abs(const Float& x) | $|x|$ |
Float fma(const Float& a, const Float& b, const Float& c, int precision) | $ab + c$(融合積和) |
Float fms(const Float& a, const Float& b, const Float& c, int precision) | $ab - c$(融合積差) |
Float fmma(const Float& a, const Float& b, const Float& c, const Float& d, int precision) | $ab + cd$(二重融合積和) |
Float fmms(const Float& a, const Float& b, const Float& c, const Float& d, int precision) | $ab - cd$(二重融合積差) |
Float factorial(int n, int precision) | $n!$ |
void sinCos(const Float& x, Float& s, Float& c, int precision) | $\sin x$ と $\cos x$ を同時計算 |
void sinhCosh(const Float& x, Float& s, Float& c, int precision) | $\sinh x$ と $\cosh x$ を同時計算 |
Float agm(const Float& a, const Float& b, int precision) | 算術幾何平均 $\mathrm{AGM}(a, b)$ |
Float sum(std::span<const Float> values, int precision) | 高精度総和 |
Float dot(std::span<const Float> a, std::span<const Float> b, int precision) | 高精度内積 |
誤差関数・ガンマ関数
| シグネチャ | 説明 |
|---|---|
Float erf(const Float& x, int precision) | 誤差関数 $\mathrm{erf}(x)$ |
Float erfc(const Float& x, int precision) | 相補誤差関数 $\mathrm{erfc}(x) = 1 - \mathrm{erf}(x)$ |
Float erfcx(const Float& x, int precision) | スケール付き相補誤差関数 $e^{x^2}\,\mathrm{erfc}(x)$ |
Float gamma(const Float& x, int precision) | $\Gamma(x)$ |
Float lnGamma(const Float& x, int precision) | $\ln\Gamma(x)$ |
Float beta(const Float& a, const Float& b, int precision) | $B(a, b) = \Gamma(a)\Gamma(b)/\Gamma(a+b)$ |
Float digamma(const Float& x, int precision) | $\psi(x) = \Gamma'(x)/\Gamma(x)$ |
Float trigamma(const Float& x, int precision) | $\psi'(x)$ |
Float polygamma(int n, const Float& x, int precision) | $\psi^{(n)}(x)$ |
Float gammaP(const Float& a, const Float& x, int precision) | 正規化下側不完全ガンマ $P(a,x)$ |
Float gammaQ(const Float& a, const Float& x, int precision) | 正規化上側不完全ガンマ $Q(a,x)$ |
Float gammaLower(const Float& a, const Float& x, int precision) | 下側不完全ガンマ $\gamma(a,x)$ |
Float gammaUpper(const Float& a, const Float& x, int precision) | 上側不完全ガンマ $\Gamma(a,x)$ |
丸め・整数部
すべて calx 名前空間のフリー関数。ムーブ版オーバーロードも提供される。
| シグネチャ | 説明 |
|---|---|
Float floor(const Float& x) | $\lfloor x \rfloor$(床関数) |
Float ceil(const Float& x) | $\lceil x \rceil$(天井関数) |
Float round(const Float& x) | 最近接丸め(half-away-from-zero: tie で 0 から遠い側) |
Float roundEven(const Float& x) | 最近接偶数丸め(banker's rounding: tie で偶数側) |
Float trunc(const Float& x) | ゼロ方向への切り捨て |
Float frac(const Float& x) | 小数部 $x - \lfloor x \rfloor$ |
Float nearbyint(const Float& x) | round と同等 |
Float rint(const Float& x) | round と同等 |
Float modf(const Float& x, Float& iptr) | 整数部を iptr に、小数部を返す |
Float fmod(const Float& x, const Float& y) | 浮動小数点剰余 $x - \mathrm{trunc}(x/y) \cdot y$ |
Float remainder(const Float& x, const Float& y) | IEEE 754 剰余 $x - \mathrm{roundEven}(x/y) \cdot y$ |
std::pair<Float, int> remquo(const Float& x, const Float& y) | remainder + 商の符号付き下位 3 ビット |
Float ldexp(const Float& x, int exp) | $x \times 2^{\mathrm{exp}}$ |
Float frexp(const Float& x, int* exp) | 仮数部 $[0.5, 1)$ と指数を分離 |
Float scalbn(const Float& x, int n) | ldexp と同等 |
int64_t ilogb(const Float& x) | $\lfloor \log_2 |x| \rfloor$ |
Float logb(const Float& x) | $\lfloor \log_2 |x| \rfloor$(Float 型で返す) |
ユーティリティ
| シグネチャ | 説明 |
|---|---|
Float fmin(const Float& a, const Float& b) | NaN を無視した最小値 |
Float fmax(const Float& a, const Float& b) | NaN を無視した最大値 |
Float fdim(const Float& a, const Float& b) | $\max(a - b, 0)$ |
Float copySign(const Float& x, const Float& y) | $y$ の符号を $x$ にコピー |
bool signBit(const Float& x) | 負なら true |
Float nextAbove(const Float& x) | $x$ より大きい最小の表現可能値 |
Float nextBelow(const Float& x) | $x$ より小さい最大の表現可能値 |
Float lerp(const Float& a, const Float& b, const Float& t, int precision) | 線形補間 $a + t(b - a)$ |
Float midpoint(const Float& a, const Float& b) | 中点 $(a + b) / 2$ |
void swap(Float& a, Float& b) noexcept | スワップ |
文字列変換
| シグネチャ | 説明 |
|---|---|
std::string toString(int precision = -1) const | 10 進科学表記 (3.14e+0) |
std::string toString(int base, int fracDigits) const | N 進数表示 (2〜36 進)。toString(2, 8) → "11.01010101"、toString(16, 4) → "3.243f" |
std::string toDecimalString(int precision = -1) const | 10 進固定小数点表記 |
std::string toScientificString(int precision = -1) const | 科学表記 ($1.23 \times 10^4$ 形式) |
double toDouble() const | double に変換(精度損失の可能性あり) |
Int toInt() const | Int に変換(小数部切り捨て) |
ostream& operator<<(ostream&, const Float&) | ストリーム出力 |
istream& operator>>(istream&, Float&) | ストリーム入力 |
内部アクセス
| シグネチャ | 説明 |
|---|---|
const Int& mantissa() const | 仮数部(多倍長整数)への参照 |
int64_t exponent() const | 指数部(2 進指数) |
bool isNegative() const | 符号フラグ |
int bitLength() const | 仮数部のビット長 |
使用例
Pi の計算
#include <math/core/mp/Float.hpp>
using namespace calx;
// 1000 桁の円周率を計算(Chudnovsky アルゴリズム)
Float::setDefaultPrecision(1000);
Float pi = Float::pi(1000);
std::cout << pi.toDecimalString(1000) << std::endl;
// 3.14159265358979323846264338327950288419716939937510...
exp / log の多倍長演算
#include <math/core/mp/Float.hpp>
using namespace calx;
int prec = 30;
Float::setDefaultPrecision(prec);
Float x("1.5");
Float ex = exp(x, prec); // e^1.5
Float lx = log(ex, prec); // ln(e^1.5) = 1.5
std::cout << "exp(1.5) = " << ex.toDecimalString(prec) << std::endl;
std::cout << "log(exp(1.5)) = " << lx.toDecimalString(prec) << std::endl;
// 30 桁精度で完全に 1.5 に一致
NaN / Infinity の安全な伝播
Float inf = Float::positiveInfinity();
Float nan = Float::nan();
Float z = Float::zero();
Float r1 = inf + Float(1); // +Inf
Float r2 = inf - inf; // NaN
Float r3 = nan + Float(42); // NaN
Float r4 = Float(1) / z; // +Inf
std::cout << r1.isInfinity() // true
<< r2.isNaN() // true
<< r3.isNaN() // true
<< r4.isInfinity(); // true
精度制御と定数キャッシュ
// thread_local キャッシュにより、同一精度での再呼び出しは高速
Float pi1 = Float::pi(500); // 初回: 計算
Float pi2 = Float::pi(500); // 2 回目: キャッシュから即時返却
Float pi3 = Float::pi(1000); // 精度が異なるため再計算
// 丸めモードの変更
Float::setRoundingMode(RoundingMode::TowardZero);
Float x("1.999");
x.setPrecision(3); // TowardZero で丸め