bin_float API

bin_float は floating の二進浮動小数点のコアです。BinFloat は符号付きの二進有理数 (−1)s⋅c⋅2e(-1)^s \cdot c \cdot 2^{e} であり、任意精度の係数、付随する作業精度、および IEEE 754 の特殊値(符号付きゼロ、無限大、ペイロード付きの quiet NaN と signaling NaN)を持ちます。すべての算術演算は厳密な結果を 1 回だけ丸めます。BinaryContext は 1 回の演算の精度、指数範囲、丸め方向、極小性(tininess)の規則を与え、*_ctx メソッドは値とともに IEEE のステータスフラグを返します。チュートリアルでは一般的なワークフローを示し、設計ページでは以下で用いる丸め・範囲・認証の規則を導出しています。検証済みの IEEE 754 の範囲は適合性に列挙されています。

moon.pkg でパッケージをインポートします:

import {
  "Luna-Flow/floating/bin_float",
}

このページを通じて、pp はビット単位の精度、∘(x)\circ(x) は有効なコンテキストのもとでの実数 xx の丸め、「フラグ」は BinaryFlags 値の 5 つの IEEE 例外フラグを表します。@lf_arith は Luna-Flow/arithmetic パッケージであり、その RoundingMode、ArithmeticContext、ArithmeticError 型がいくつかのシグネチャに現れます(インターフェースファイルではパッケージは @arithmetic と表示されます)。

演算を呼び出す 3 つの方法

ほとんどの演算には、1 つの数値アルゴリズムを背後に持つ最大 3 つの形式があります。

形式例コンテキスト結果
plainx + y, x.exp()非有界な指数範囲、最近接偶数丸め、オペランドの精度値のみ
contextualx.add_ctx(y, ctx), x.exp_ctx(ctx)与えられた BinaryContext(value, flags)
checkedx.try_exp_ctx(ctx), x.div_checked(y)与えられたコンテキスト、または plain のもの@lf_arith.ArithmeticError を伴う Result

二項演算の plain 形式は、2 つのオペランドの精度のうち大きい方(fma では 3 つのうち最大のもの)で動作します。指数範囲は後述の実装範囲なので、無限大へのオーバーフローや、符号付きゼロまたは極小値へのアンダーフローは、およそ 2±2302^{\pm 2^{30}} でしか起こりません。

値と限界

binary_implementation_e_max, binary_implementation_e_min

有限な BinFloat が持ち得る先頭ビットの指数の最大値と最小値です。

pub let binary_implementation_e_max : Int
pub let binary_implementation_e_min : Int

それらは 230−1=10737418232^{30}-1 = 1073741823 と −(230−1)-(2^{30}-1) です。非有界なコンテキストとすべての plain 演算は、これらを emax⁡e_{\max} と emin⁡e_{\min} として用います。先頭ビットが emax⁡e_{\max} より上に来る結果はオーバーフローし、emin⁡e_{\min} より下では値は量子 2emin⁡−p+12^{e_{\min}-p+1} の非正規化数になります。明示的な範囲を持つコンテキストは、この範囲との共通部分をとります。

binary_precision_max

BinaryContext が受け付ける最大の精度です。

pub let binary_precision_max : Int

これは 228=2684354562^{28} = 268435456 ビットです。指数範囲と合わせて、すべての係数の指数を 32 ビット Int の範囲内に収めます。

厳密な係数

BinCoeff

非負の任意精度整数であり、BinFloat の係数として、また交換形式のエンコーディングのビットパターンとして使われます。

pub struct BinCoeff {
  // private fields
} derive(@debug.Debug)

BinCoeff 上の算術演算はすべて厳密です。ネイティブ、LLVM、Wasm ターゲットでは、値はインラインの 64 ビットまたは 128 ビットのワード、あるいは 32 ビットのリムの配列であり、JavaScript ではホストの bigint です。表現は観測できず、アルゴリズムの選択(筆算法、Karatsuba、Toom-3、数論変換、段階的除算)は設計ページで説明しています。数学的な結果が負または未定義になり得る演算は検査され、代わりにメッセージ付きの Err を返します。

BinCoeff::zero, BinCoeff::one, BinCoeff::from_uint64

機械値から係数を構築します。

pub fn BinCoeff::zero() -> Self
pub fn BinCoeff::one() -> Self
pub fn BinCoeff::from_uint64(UInt64) -> Self

BinCoeff::parse, BinCoeff::to_string, BinCoeff::to_radix_string

係数と数字列の間で変換します。

pub fn BinCoeff::parse(String, radix? : Int) -> Result[Self, String]
pub fn BinCoeff::to_string(Self) -> String
pub fn BinCoeff::to_radix_string(Self, Int) -> String

parse は基数 radix(既定値 10、9 を超える数字には英字、先頭の + は省略可)の数字列を読み取ります。空文字列、- 符号、基数の範囲外の数字、[2,36][2, 36] の範囲外の基数は Err になります。to_string は 10 進で、to_radix_string は [2,36][2, 36] の任意の基数で、接頭辞なしの小文字で出力します。それ以外の基数ではアボートします。

BinCoeff::from_bytes_be, BinCoeff::to_bytes_be

係数とビッグエンディアンのバイト列の間で変換します。

pub fn BinCoeff::from_bytes_be(BytesView) -> Self
pub fn BinCoeff::to_bytes_be(Self) -> Bytes

to_bytes_be は最小のバイト数を用います。先頭のゼロバイトは from_bytes_be によって無視されます。

BinCoeff::to_uint64

値を UInt64 として返し、64 ビットを超える場合は None を返します。

pub fn BinCoeff::to_uint64(Self) -> UInt64?

BinCoeff::is_zero, BinCoeff::bit_length, BinCoeff::ctz, BinCoeff::test_bit

ビットレベルの問い合わせ。

pub fn BinCoeff::is_zero(Self) -> Bool
pub fn BinCoeff::bit_length(Self) -> Int
pub fn BinCoeff::ctz(Self) -> Int
pub fn BinCoeff::test_bit(Self, Int) -> Bool

bit_length は c>0c > 0 に対して ⌊log⁡2c⌋+1\lfloor \log_2 c \rfloor + 1、ゼロに対して 00 です。ctz は末尾のゼロビットを数えます(2 進付値 ν2(c)\nu_2(c))。test_bit(i) は、最下位ビットを 00 として数えたビット ii です。

BinCoeff::compare, BinCoeff::equal

厳密な比較。

pub fn BinCoeff::compare(Self, Self) -> Int
pub fn BinCoeff::equal(Self, Self) -> Bool
pub fn BinCoeff::not_equal(Self, Self) -> Bool
pub fn BinCoeff::op_lt(Self, Self) -> Bool
pub fn BinCoeff::op_le(Self, Self) -> Bool
pub fn BinCoeff::op_gt(Self, Self) -> Bool
pub fn BinCoeff::op_ge(Self, Self) -> Bool

compare は −1-1、00、11 のいずれかを返します。演算子メソッドは型に昇格された Compare と Eq のトレイトメソッドです。演算子 <、== などを使ってください。

BinCoeff::add, BinCoeff::mul, BinCoeff::square, BinCoeff::pow_nat

厳密な加算、乗算、平方、べき乗。

pub fn BinCoeff::add(Self, Self) -> Self
pub fn BinCoeff::mul(Self, Self) -> Self
pub fn BinCoeff::square(Self) -> Self
pub fn BinCoeff::pow_nat(Self, UInt) -> Self

square は交差項の対称性を利用する専用カーネルを用います。pow_nat(0) は 000^0 を含めて 1 です。

BinCoeff::sub_checked, BinCoeff::div_rem_checked

自然数では失敗し得る、減算とユークリッド除算。

pub fn BinCoeff::sub_checked(Self, Self) -> Result[Self, String]
pub fn BinCoeff::div_rem_checked(Self, Self) -> Result[(Self, Self), String]

a.sub_checked(b) は b>ab > a のとき Err です。n.div_rem_checked(d) は n=qd+rn = qd + r かつ 0≤r<d0 \le r < d を満たす (q,r)(q, r) を返し、d=0d = 0 のとき Err です。

BinCoeff::gcd

最大公約数を返します。

pub fn BinCoeff::gcd(Self, Self) -> Self

gcd⁡(a,0)=a\gcd(a, 0) = a、gcd⁡(0,0)=0\gcd(0, 0) = 0 です。

BinCoeff::shift_left, BinCoeff::shift_right, BinCoeff::shl, BinCoeff::shr

2k2^k を掛けるか、2k2^k で割ってゼロ方向に丸めます。

pub fn BinCoeff::shift_left(Self, Int) -> Self
pub fn BinCoeff::shift_right(Self, Int) -> Self
pub fn BinCoeff::shl(Self, Int) -> Self
pub fn BinCoeff::shr(Self, Int) -> Self

shl と shr は、<< と >> の背後にある Shl/Shr トレイトメソッドです。負のシフト量はアボートします。

BinCoeff::bit_and, BinCoeff::bit_or, BinCoeff::bit_xor

二進展開に対するビット演算。

pub fn BinCoeff::bit_and(Self, Self) -> Self
pub fn BinCoeff::bit_or(Self, Self) -> Self
pub fn BinCoeff::bit_xor(Self, Self) -> Self

BinCoeff のトレイト実装

BinCoeff は Add、Mul、Shl、Shr、Eq、Compare、Show、Debug を実装します。output と to_repr は昇格された Show と Debug のメソッドです。

pub fn BinCoeff::output(Self, &Logger) -> Unit
pub fn BinCoeff::to_repr(Self) -> @debug.Repr
pub impl Add for BinCoeff
pub impl Compare for BinCoeff
pub impl Eq for BinCoeff
pub impl Mul for BinCoeff
pub impl Shl for BinCoeff
pub impl Show for BinCoeff
pub impl Shr for BinCoeff
///|
test "BinCoeff is exact natural-number arithmetic" {
  let c = @bin_float.BinCoeff::parse("ff", radix=16).unwrap()
  let ten = @bin_float.BinCoeff::from_uint64(10UL)
  let (q, r) = c.div_rem_checked(ten).unwrap()
  inspect("\{q} \{r} \{c.gcd(ten)} \{c.bit_length()}", content="25 5 5 8")
  inspect(ten.pow_nat(20), content="100000000000000000000")
  inspect(ten.sub_checked(c) is Err(_), content="true")
}

値の型

BinFloat

二進浮動小数点値です。有限の二進有理数、符号付き無限大、または NaN であり、作業精度を持ちます。

pub struct BinFloat {
  // private fields
} derive(Eq, @debug.Debug)

有限な値は (−1)s⋅c⋅2e(-1)^s \cdot c \cdot 2^{e} であり、ss は符号ビット、cc は BinCoeff、ee は exponent2() です。この API で構築されるすべての値は正規化されています。非ゼロの cc は奇数であり(2 の因子は ee に移されます)、ゼロは c=0c = 0 かつ e=0e = 0 で符号を保持し、cc は高々 precision() ビットです。精度は値の属性です。plain 演算はオペランドの精度のうち大きい方で動作し、contextual 演算は結果にコンテキストの精度を刻印します。

導出された Eq は数値的ではなく構造的です。符号、クラス、係数、指数、精度、NaN の状態がすべて一致するとき 2 つの値は == となるので、one(precision=53) != one(precision=24)、-0 != +0 であり、NaN は同一の NaN と == になります。数値的な比較には compare、compare_quiet、total_order を使ってください。

BinFloat::make

precision ビットに丸めた有限値 (−1)negative⋅c⋅2e(-1)^{\text{negative}} \cdot c \cdot 2^{e} を構築します。

pub fn BinFloat::make(BinCoeff, Int, Int, negative? : Bool, mode? : @arithmetic.RoundingMode) -> Self

引数は係数、指数 ee、精度です。係数の有効ビット数が精度より多い場合は mode(既定値 ToNearestEven)で丸められます。結果は正規化されます。1 未満の精度は 1 として扱われます。実装の指数範囲外の値は、オーバーフローやアンダーフローと同様に、mode に応じて無限大またはゼロになります。

BinFloat::from_coefficient, BinFloat::from_int

整数から値を構築します。

pub fn BinFloat::from_coefficient(BinCoeff, precision? : Int, negative? : Bool) -> Self
pub fn BinFloat::from_int(Int, precision? : Int) -> Self

既定の精度は 53 です。整数の有効ビット数が精度より多い場合は最近接偶数丸めされます。既定の精度では、from_int(n) はすべての Int に対して厳密です。

BinFloat::from_double, BinFloat::from_float

ホストの binary64 または binary32 の値を厳密にデコードします。

pub fn BinFloat::from_double(Double, precision? : Int) -> Self
pub fn BinFloat::from_float(Float, precision? : Int) -> Self

既定値は 53 ビットと 24 ビットなので、変換は厳密です。符号付きゼロ、無限大、NaN の符号、quiet/signaling の区別、NaN のペイロードは保存されます。値はホストがすでに丸めたものです。from_double(0.1) は 10 分の 1 ではなく 3602879701896397⋅2−553602879701896397 \cdot 2^{-55} です。十進リテラルを直接丸めるには from_string を使ってください。

BinFloat::zero, BinFloat::negative_zero, BinFloat::one, BinFloat::inf

定数 +0+0、−0-0、11、±∞\pm\infty を構築します。

pub fn BinFloat::zero(precision? : Int) -> Self
pub fn BinFloat::negative_zero(precision? : Int) -> Self
pub fn BinFloat::one(precision? : Int) -> Self
pub fn BinFloat::inf(@def.Sign, precision? : Int) -> Self

既定の精度は 53 です。inf(Sign::Negative) は −∞-\infty であり、その他の符号では +∞+\infty になります。

BinFloat::nan, BinFloat::quiet_nan, BinFloat::signaling_nan

NaN を構築します。

pub fn BinFloat::nan(precision? : Int) -> Self
pub fn BinFloat::quiet_nan(payload? : BinCoeff, negative? : Bool, precision? : Int) -> Self
pub fn BinFloat::signaling_nan(payload? : BinCoeff, negative? : Bool, precision? : Int) -> Self

nan() はペイロード 0 の正の quiet NaN です。signaling NaN は常に非ゼロのペイロードを持ちます(既定値も、要求された 0 も 1 になります)。ペイロードは演算を通じて引き継がれ、値が交換形式にエンコードされるときにだけペイロードフィールドに切り詰められます。

値の観測

BinFloat::classify, BinFloat::sign, BinFloat::is_negative

値のクラスと符号を報告します。

pub fn BinFloat::classify(Self) -> @arithmetic.FpClass
pub fn BinFloat::sign(Self) -> @def.Sign
pub fn BinFloat::is_negative(Self) -> Bool

classify は Finite、Infinity、NaN のいずれかを返します(ゼロは Finite)。sign はすべてのゼロとすべての NaN に対して Zero であり、それ以外は Positive または Negative です。is_negative は符号ビットそのものを返し、これは −0-0、−∞-\infty、負の NaN で立っています。@def.is_finite、@def.is_nan、@def.is_infinite、@def.is_zero は Floating トレイトを通じて BinFloat に使えます。

BinFloat::is_zero, BinFloat::is_negative_zero, BinFloat::is_quiet_nan, BinFloat::is_signaling_nan, BinFloat::nan_payload

特殊値の述語。

pub fn BinFloat::is_zero(Self) -> Bool
pub fn BinFloat::is_negative_zero(Self) -> Bool
pub fn BinFloat::is_quiet_nan(Self) -> Bool
pub fn BinFloat::is_signaling_nan(Self) -> Bool
pub fn BinFloat::nan_payload(Self) -> BinCoeff

nan_payload は NaN でない値に対してはゼロです。

BinFloat::coefficient, BinFloat::exponent2, BinFloat::precision

格納された表現を返します。

pub fn BinFloat::coefficient(Self) -> BinCoeff
pub fn BinFloat::exponent2(Self) -> Int
pub fn BinFloat::precision(Self) -> Int

有限な値では、数は coefficient() ×2exponent2()\times 2^{\texttt{exponent2()}} に符号を適用したものです。無限大や NaN の係数と指数には意味がありません。

BinFloat::normalized

有限な値の、それ自身の精度での正準表現を返します。

pub fn BinFloat::normalized(Self) -> Self

公開 API で構築された値はすでに正準形なので、それらに対しては恒等写像です。無限大と NaN はそのまま返されます。

BinFloat::with_precision

値を新しい作業精度に丸めます。

pub fn BinFloat::with_precision(Self, Int, @arithmetic.RoundingMode) -> Self

新しい精度より多くの有効ビットを持つ有限な値は、指定された方向に丸められます(@lf_arith.RoundingMode には ties-to-away モードがないので、その場合は round_ctx を使ってください)。ゼロ、無限大、NaN は精度属性だけが変わります。フラグは報告されないので、フラグが重要な場合は round_ctx を使ってください。

BinFloat::ulp

有限な値の、それ自身の精度での最終桁の単位(ulp)を返します。

pub fn BinFloat::ulp(Self) -> Self

先頭ビットの指数が t=⌊log⁡2∣x∣⌋t = \lfloor \log_2 |x| \rfloor である x≠0x \ne 0 に対して、結果は 2t−p+12^{t-p+1} です。ゼロに対しては 21−p2^{1-p}、無限大や NaN に対しては quiet NaN です。この間隔はコンテキストの指数範囲を無視するため、IEEE 形式の非正規化数の間隔ではありません。

///|
test "make normalizes and rounds to the precision" {
  let twelve = @bin_float.BinFloat::make(
    @bin_float.BinCoeff::from_uint64(12UL),
    0,
    2,
  )
  inspect(
    "\{twelve} \{twelve.coefficient()} \{twelve.exponent2()}",
    content="3p2 3 2",
  )
  // 13 needs four bits; at two bits it rounds to nearest-even 12.
  let thirteen = @bin_float.BinFloat::make(
    @bin_float.BinCoeff::from_uint64(13UL),
    0,
    2,
  )
  inspect(thirteen, content="3p2")
  inspect(@bin_float.BinFloat::one().ulp(), content="1p-52")
}

plain 算術演算

BinFloat::add, BinFloat::sub, BinFloat::mul, BinFloat::div, BinFloat::neg

四則演算と符号反転であり、+、-、*、/、単項 - としても利用できます。

pub fn BinFloat::add(Self, Self) -> Self
pub fn BinFloat::sub(Self, Self) -> Self
pub fn BinFloat::mul(Self, Self) -> Self
pub fn BinFloat::div(Self, Self) -> Self
pub fn BinFloat::neg(Self) -> Self
pub impl Add for BinFloat
pub impl Sub for BinFloat
pub impl Mul for BinFloat
pub impl Div for BinFloat
pub impl Neg for BinFloat

結果は、厳密な和・差・積・商を、オペランドの精度のうち大きい方へ、実装の指数範囲で 1 回だけ最近接偶数丸めしたものです。特殊値は IEEE 754 に従います。NaN は伝播し(最初の NaN オペランドを quiet にしたもの)、∞−∞\infty - \infty、0⋅∞0 \cdot \infty、0/00/0、∞/∞\infty/\infty は NaN、非ゼロの数をゼロで割ると符号付き無限大になります。フラグは破棄されるので、観測するにはcontextual 形式を使ってください。neg はゼロや NaN を含むすべての値の符号ビットを反転し、丸めは一切行いません。

BinFloat::abs, BinFloat::copy_sign

符号ビットをクリアまたはコピーします。

pub fn BinFloat::abs(Self) -> Self
pub fn BinFloat::copy_sign(Self, Self) -> Self

どちらも IEEE の quiet な符号ビット演算です。丸めることも、フラグを立てることもなく、NaN のペイロードを保持します。x.copy_sign(y) は x の絶対値と y の符号ビットを持ちます。

BinFloat::div_checked

除算を行い、除数がゼロの場合はエラーを返します。

pub fn BinFloat::div_checked(Self, Self) -> Result[Self, @arithmetic.ArithmeticError]

有限なゼロの除数(0/00/0 を含む)からは division_by_zero エラーが得られます。それ以外では結果は div と同じです。

BinFloat::sqrt, sqrt_for_precision, sqrt_bounds_for_precision

正しく丸められた平方根。

pub fn BinFloat::sqrt(Self) -> Result[Self, @arithmetic.ArithmeticError]
pub fn sqrt_for_precision(BinFloat, Int) -> Result[BinFloat, @arithmetic.ArithmeticError]
pub fn sqrt_bounds_for_precision(BinFloat, Int) -> Result[(BinFloat, BinFloat), @arithmetic.ArithmeticError]

x.sqrt() は x\sqrt{x} を x の精度へ最近接偶数丸めし、sqrt_for_precision(x, p) は同じことを精度 p で行います。どちらも負の非ゼロの引数(−∞-\infty と符号ビットが立った NaN を含む)に対しては domain_error を返します。−0=−0\sqrt{-0} = -0 であり、正の NaN からは quiet NaN の Ok が得られます。sqrt_bounds_for_precision(x, p) は (RD⁡p(x),RU⁡p(x))(\operatorname{RD}_p(\sqrt x), \operatorname{RU}_p(\sqrt x)) を返します。これは幅が高々 1 ulp の包含区間であり、根が厳密な場合は 1 点に縮退します。有限で非負の引数が必要で、NaN や無限大は unsupported、負の値は domain_error になります。

BinFloat::pow_int, BinFloat::pown

値を整数乗します。

pub fn BinFloat::pow_int(Self, Int) -> Result[Self, @arithmetic.ArithmeticError]
pub fn BinFloat::pown(Self, Int) -> Result[Self, @arithmetic.ArithmeticError]

2 つの名前は同じ関数です。結果は xnx^n を x の精度へ正しく最近接偶数丸めしたもので、pow_int_ctx と同様に計算されます。ゼロの底と負の指数は division_by_zero エラーです。NaN を含むすべての xx に対して x0=1x^0 = 1 です。

BinFloat::fma

積和演算(fused multiply-add): 1 回の丸めによる x⋅y+zx \cdot y + z。

pub fn BinFloat::fma(Self, Self, Self) -> Self

精度は 3 つのオペランドの精度のうち最大のものです。特殊なケースについては fma_ctx を参照してください。

BinFloat::remainder

IEEE 754 の剰余 x−nyx - n y。ここで nn は x/yx/y に最も近い整数で、同点の場合は偶数を選びます。

pub fn BinFloat::remainder(Self, Self) -> Self

結果は、オペランドの精度のうち大きい方に収まる限り厳密であり、その精度のオペランドに対しては常にそうなります(証明は設計ページにあります)。remainder_ctx を参照してください。

///|
test "plain arithmetic rounds once at the operand precision" {
  let one = @bin_float.BinFloat::one()
  let three = @bin_float.BinFloat::from_int(3)
  let third = one / three
  inspect(third, content="6004799503160661p-54")
  inspect(third.to_shortest_string(), content="0.3333333333333333")
  inspect(one / @bin_float.BinFloat::zero(), content="inf")
  inspect(@bin_float.BinFloat::from_int(7).remainder(@bin_float.BinFloat::from_int(2)), content="-1p0")
  inspect(@bin_float.BinFloat::from_int(3).pow_int(-2).unwrap().to_shortest_string(), content="0.1111111111111111")
}

コンテキスト、丸め、フラグ

BinaryRoundingMode

コンテキストの丸め方向属性です。

pub(all) enum BinaryRoundingMode {
  RoundTiesToEven
  RoundTiesToAway
  RoundTowardZero
  RoundTowardPositive
  RoundTowardNegative
  RoundAwayFromZero
} derive(Eq, @debug.Debug)
pub fn BinaryRoundingMode::equal(Self, Self) -> Bool
pub fn BinaryRoundingMode::not_equal(Self, Self) -> Bool
pub fn BinaryRoundingMode::to_repr(Self) -> @debug.Repr

最初の 5 つは IEEE 754-2019 の丸め方向(4.3 節)です。RoundAwayFromZero は追加の方向付き丸めモード(絶対値を切り上げる)で、GDA 流の @lf_arith.RoundingMode::AwayFromZero で使われます。各モードは単調な写像 R→F∪{±∞}\mathbb{R} \to F \cup \{\pm\infty\} であり、設計ページで定義されています。

BinaryRoundingMode::from_arithmetic, BinaryRoundingMode::to_arithmetic

@lf_arith.RoundingMode との相互変換を行います。

pub fn BinaryRoundingMode::from_arithmetic(@arithmetic.RoundingMode) -> Self
pub fn BinaryRoundingMode::to_arithmetic(Self) -> @arithmetic.RoundingMode?

@lf_arith.RoundingMode には ties-to-away モードがないため、to_arithmetic(RoundTiesToAway) は None です。その他のモードは一対一に対応します。

TininessDetection

非ゼロの結果が、アンダーフローフラグの判定において極小とみなされる条件です。

pub(all) enum TininessDetection {
  BeforeRounding
  AfterRounding
} derive(Eq, @debug.Debug)
pub fn TininessDetection::equal(Self, Self) -> Bool
pub fn TininessDetection::not_equal(Self, Self) -> Bool
pub fn TininessDetection::to_repr(Self) -> @debug.Repr

BeforeRounding は、厳密な値が ∣x∣<2emin⁡|x| < 2^{e_{\min}} を満たすときに結果を極小とみなします。AfterRounding は、xx を非有界な指数範囲で pp ビットに丸めた値の絶対値が 2emin⁡2^{e_{\min}} 未満のときに極小とみなします(IEEE 754-2019 7.5 節)。既定値は AfterRounding です。アンダーフローは、極小かつ不正確な結果に対してのみ通知されます。

BinaryContext

1 回の演算の精度、丸め方向、指数範囲、極小性の規則です。

pub struct BinaryContext {
  // private fields
} derive(Eq, @debug.Debug)
pub fn BinaryContext::equal(Self, Self) -> Bool
pub fn BinaryContext::not_equal(Self, Self) -> Bool
pub fn BinaryContext::to_repr(Self) -> @debug.Repr

コンテキストは不変な値であり、グローバルな状態やスレッドの状態はありません。emin⁡e_{\min} と emax⁡e_{\max} は IEEE 754 と同様に先頭ビットの指数です。正規化数は 2emin⁡≤∣x∣<2emax⁡+12^{e_{\min}} \le |x| < 2^{e_{\max}+1} を満たし、最大の有限値は (2−21−p) 2emax⁡(2 - 2^{1-p})\,2^{e_{\max}}、最小の正の非正規化数は 2emin⁡−p+12^{e_{\min}-p+1} です。範囲の指定がない場合は実装の範囲を意味します。

BinaryContext::new, BinaryContext::try_new, BinaryContext::unbounded

コンテキストを構築します。

pub fn BinaryContext::new(Int, rounding? : BinaryRoundingMode, e_min? : Int, e_max? : Int, tininess? : TininessDetection) -> Self
pub fn BinaryContext::try_new(Int, rounding? : BinaryRoundingMode, e_min? : Int, e_max? : Int, tininess? : TininessDetection) -> Result[Self, @arithmetic.ArithmeticError]
pub fn BinaryContext::unbounded(Int, rounding? : BinaryRoundingMode) -> Self

最初の引数は精度 pp です。既定値は RoundTiesToEven、明示的な指数範囲なし、AfterRounding です。p≤0p \le 0 のとき、p>p > binary_precision_max のとき、または両方の範囲が与えられて emin⁡>emax⁡e_{\min} > e_{\max} のとき、new はアボートし、try_new は domain_error を返します。unbounded(p) は明示的な範囲を持たないため、実装の範囲だけが適用されます。

BinaryContext::binary16, BinaryContext::binary32, BinaryContext::binary64, BinaryContext::binary128

IEEE 754 の交換形式のコンテキストです。

pub fn BinaryContext::binary16(rounding? : BinaryRoundingMode, tininess? : TininessDetection) -> Self
pub fn BinaryContext::binary32(rounding? : BinaryRoundingMode, tininess? : TininessDetection) -> Self
pub fn BinaryContext::binary64(rounding? : BinaryRoundingMode, tininess? : TininessDetection) -> Self
pub fn BinaryContext::binary128(rounding? : BinaryRoundingMode, tininess? : TininessDetection) -> Self

それぞれ、その形式の BinaryInterchangeFormat::context です:

コンテキストppemin⁡e_{\min}emax⁡e_{\max}
binary1611−1415
binary3224−126127
binary6453−10221023
binary128113−1638216383

BinaryContext::from_arithmetic_context

@lf_arith.ArithmeticContext を変換します。

pub fn BinaryContext::from_arithmetic_context(@arithmetic.ArithmeticContext) -> Self

精度、丸め、省略可能な範囲がコピーされます。clamp フィールドは二進では意味を持たないため無視され、極小性は AfterRounding です。[1,228][1, 2^{28}] の範囲外の精度は、new と同様にアボートします。

BinaryContext::precision, BinaryContext::rounding, BinaryContext::e_min, BinaryContext::e_max, BinaryContext::tininess

コンテキストのフィールドを読み取ります。

pub fn BinaryContext::precision(Self) -> Int
pub fn BinaryContext::rounding(Self) -> BinaryRoundingMode
pub fn BinaryContext::e_min(Self) -> Int?
pub fn BinaryContext::e_max(Self) -> Int?
pub fn BinaryContext::tininess(Self) -> TininessDetection

e_min と e_max は与えられたとおりの範囲(非有界な側は None)を返し、実装の範囲との共通部分はとりません。

BinaryFlags

1 つ以上の演算によって立てられた、5 つの IEEE 754 例外フラグです。

pub struct BinaryFlags {
  // private fields
} derive(Eq, @debug.Debug)
pub fn BinaryFlags::new() -> Self
pub fn BinaryFlags::inexact(Self) -> Bool
pub fn BinaryFlags::underflow(Self) -> Bool
pub fn BinaryFlags::overflow(Self) -> Bool
pub fn BinaryFlags::division_by_zero(Self) -> Bool
pub fn BinaryFlags::invalid_operation(Self) -> Bool
pub fn BinaryFlags::equal(Self, Self) -> Bool
pub fn BinaryFlags::not_equal(Self, Self) -> Bool
pub fn BinaryFlags::to_repr(Self) -> @debug.Repr

new() はすべてのフラグがクリアされた状態です。contextual 演算は自身が立てたフラグだけを返し、フラグを結合するまでは何もスティッキーではありません。各フラグの意味は次のとおりです。inexact は返された値が厳密な結果と異なること、underflow は結果が極小かつ不正確であること、overflow は丸めた結果が最大の有限値を超えたこと(常に inexact とともに立ちます)、division_by_zero は有限なオペランドから厳密な無限大の結果が得られたこと(1/01/0 や log⁡0\log 0 など)、invalid_operation は有用な実数の結果が存在せず quiet NaN が返されたこと、または signaling NaN がオペランドだったことを表します。

BinaryFlags::combine

2 つのフラグ集合の和を返します。

pub fn BinaryFlags::combine(Self, Self) -> Self

combine はビットごとの OR です。結合的、可換、冪等であり new() を単位元とするので、計算のフラグは任意の順序で蓄積できます。

BinaryFlags::to_testfloat_bits

フラグを Berkeley TestFloat のビット配置でエンコードします。

pub fn BinaryFlags::to_testfloat_bits(Self) -> Int

inexact は 0x01、underflow は 0x02、overflow は 0x04、division by zero は 0x08、invalid は 0x10 です。

contextual 算術演算

このグループのすべてのメソッドは (value, flags) を返し、厳密な結果をコンテキストのもとで 1 回だけ丸め、コンテキストの指数範囲を適用します。オーバーフローでは丸め方向に応じて ±∞\pm\infty または最大の有限の絶対値が返され、極小な結果は量子 2emin⁡−p+12^{e_{\min}-p+1} の非正規化数の格子上で丸められます。返される値はコンテキストの精度を持ちます。NaN のオペランドからは、最初の NaN オペランドを quiet にしたもの(符号とペイロードを保持)が得られ、invalid_operation はいずれかのオペランドが signaling NaN だった場合にのみ立ちます。

BinFloat::round_ctx

値をコンテキストへ丸めます。

pub fn BinFloat::round_ctx(Self, BinaryContext) -> (Self, BinaryFlags)

これは、より広い値をより狭い形式へ変換する IEEE の変換です。有限な値はオーバーフロー、非正規化数、極小性の規則をすべて適用して丸められ、無限大は保持され、signaling NaN は invalid_operation とともに quiet にされます。

BinFloat::add_ctx, BinFloat::sub_ctx, BinFloat::mul_ctx, BinFloat::div_ctx

コンテキストのもとでの四則演算。

pub fn BinFloat::add_ctx(Self, Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::sub_ctx(Self, Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::mul_ctx(Self, Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::div_ctx(Self, Self, BinaryContext) -> (Self, BinaryFlags)
x.op_ctx(y, ctx)=(∘(xopy), flags).\texttt{x.op\_ctx(y, ctx)} = \bigl(\circ(x \mathbin{\mathrm{op}} y),\ \text{flags}\bigr).

不正な演算(sub の符号反転後に同符号となる ∞−∞\infty - \infty、0⋅∞0 \cdot \infty、0/00/0、∞/∞\infty/\infty)からは invalid_operation とともに quiet NaN が得られ、非ゼロの有限数をゼロで割ると division_by_zero とともに符号付き無限大が得られます。異符号のオペランドの厳密な和がゼロになる場合は +0+0 ですが、RoundTowardNegative のもとでは −0-0 です。(−0)+(−0)=−0(-0) + (-0) = -0 です(IEEE 754-2019 6.3 節)。

BinFloat::sqrt_ctx

コンテキストのもとでの平方根。

pub fn BinFloat::sqrt_ctx(Self, BinaryContext) -> (Self, BinaryFlags)

±0=±0\sqrt{\pm 0} = \pm 0、+∞=+∞\sqrt{+\infty} = +\infty であり、負の非ゼロの引数からは invalid_operation とともに quiet NaN が得られます。

BinFloat::fma_ctx

コンテキストのもとでの積和演算 ∘(x⋅y+z)\circ(x \cdot y + z)。

pub fn BinFloat::fma_ctx(Self, Self, Self, BinaryContext) -> (Self, BinaryFlags)

積は厳密に計算され、和が 1 回だけ丸められます(IEEE 754-2019 5.4.1 節)。NaN のオペランドがあれば、self、乗数、加数の順で最初の NaN が伝播します。invalid_operation は、signaling NaN、∞⋅0\infty \cdot 0(SoftFloat と同様に、加数が quiet NaN の場合も含む)、±∞⋅y+(∓∞)\pm\infty \cdot y + (\mp\infty) に対して立てられます。

BinFloat::remainder_ctx

コンテキストのもとでの IEEE 754 の剰余。

pub fn BinFloat::remainder_ctx(Self, Self, BinaryContext) -> (Self, BinaryFlags)

結果は n=round_ties_even⁡(x/y)n = \operatorname{round\_ties\_even}(x/y) として r=x−nyr = x - n y であり、∣r∣≤∣y∣/2|r| \le |y|/2 です。ゼロの結果は xx の符号を持ちます。x=±∞x = \pm\infty または y=0y = 0 からは invalid_operation とともに quiet NaN が得られ、y=±∞y = \pm\infty または x=0x = 0 のときは xx をコンテキストへ丸めたものを返します。その後、厳密な rr が丸められます。コンテキストで表現可能なオペランドに対してはこの丸めは厳密であり、フラグは立ちません。商が計算されることはありません。オペランドは 2y2y を法として還元されるため、指数の差が非常に大きくても O(log⁡)O(\log) 回の乗算で済みます。

BinFloat::pow_int_ctx, BinFloat::pown_ctx

コンテキストのもとでの整数乗 ∘(xn)\circ(x^n)。

pub fn BinFloat::pow_int_ctx(Self, Int, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::pown_ctx(Self, Int, BinaryContext) -> (Self, BinaryFlags)

2 つの名前は同じ関数で、IEEE 754 の pown です。NaN を含むすべての xx に対して x0=1x^0 = 1 であり、(±0)n<0=±∞(\pm 0)^{n<0} = \pm\infty(符号は nn が奇数の場合)で division_by_zero が立ちます。(±∞)n(\pm\infty)^n は無限大またはゼロで、奇数乗の場合はその符号を持ちます。小さなべきは厳密に計算され、それ以外では Ziv ループが包含区間を丸め、厳密な計算へのフォールバックもあるため、結果は常に正しく丸められます。

///|
test "contextual operations return value and flags" {
  let ctx = @bin_float.BinaryContext::binary32()
  let one = @bin_float.BinFloat::one()
  let (third, flags) = one.div_ctx(@bin_float.BinFloat::from_int(3), ctx)
  inspect(third.to_shortest_string_ctx(ctx), content="0.33333334")
  inspect(flags.to_testfloat_bits(), content="1")
  let (inf, zero_flags) = one.div_ctx(@bin_float.BinFloat::zero(), ctx)
  inspect("\{inf} \{zero_flags.division_by_zero()}", content="inf true")
}

IEEE 754 の演算

BinFloat::to_integral_value_ctx, BinFloat::to_integral_exact_ctx

コンテキストの丸め方向で整数値に丸めます。

pub fn BinFloat::to_integral_value_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::to_integral_exact_ctx(Self, BinaryContext) -> (Self, BinaryFlags)

これらは IEEE の roundToIntegral(コンテキストの方向)と roundToIntegralExact です。コンテキストの丸め方向だけが使われ、結果はオペランドの精度とゼロの結果の符号を保持します。to_integral_exact_ctx は値が変化したときに inexact を立て、to_integral_value_ctx は決して立てません。無限大はそのまま返され、signaling NaN は invalid_operation とともに quiet にされます。

BinFloat::floor, BinFloat::ceil, BinFloat::trunc, BinFloat::round, BinFloat::round_ties_even

固定の方向で整数値に丸めます。

pub fn BinFloat::floor(Self) -> Self
pub fn BinFloat::ceil(Self) -> Self
pub fn BinFloat::trunc(Self) -> Self
pub fn BinFloat::round(Self) -> Self
pub fn BinFloat::round_ties_even(Self) -> Self

これらは roundToIntegralTowardNegative、…TowardPositive、…TowardZero、…TiesToAway、…TiesToEven です。round はちょうど中間の場合をゼロから遠ざかる方向に丸めます。round(-2.5) = -3 ですが、round_ties_even(-2.5) = -2 です。

BinFloat::to_int_ctx, BinFloat::to_int64_ctx, BinFloat::to_uint_ctx, BinFloat::to_uint64_ctx

コンテキストの方向で丸めて機械整数へ変換する IEEE の convertToInteger です。

pub fn BinFloat::to_int_ctx(Self, BinaryContext, exact? : Bool) -> (Int?, BinaryFlags)
pub fn BinFloat::to_int64_ctx(Self, BinaryContext, exact? : Bool) -> (Int64?, BinaryFlags)
pub fn BinFloat::to_uint_ctx(Self, BinaryContext, exact? : Bool) -> (UInt?, BinaryFlags)
pub fn BinFloat::to_uint64_ctx(Self, BinaryContext, exact? : Bool) -> (UInt64?, BinaryFlags)

値はまず整数に丸められます。その整数が対象の型に収まれば結果は Some であり、exact=true(convertToIntegerExact)の場合は、丸めによって値が変化したときに inexact が立ちます。NaN、無限大、対象の範囲外の整数からは invalid_operation とともに None が得られます(C の実装なら未規定の番兵値を返すところです)。ゼロに丸められる負の値は、符号なしの対象型では 0 に変換されます。

BinFloat::next_up_ctx, BinFloat::next_down_ctx

コンテキストの形式における IEEE の nextUp と nextDown。

pub fn BinFloat::next_up_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::next_down_ctx(Self, BinaryContext) -> (Self, BinaryFlags)

next_up_ctx(x) は、xx より大きいコンテキストの形式(精度と指数範囲、非正規化数を含む)の最小の値であり、next_down_ctx は −next_up(−x)-\texttt{next\_up}(-x) です。コンテキストの丸め方向は無視されます。これらの演算は quiet です。nextUp⁡(±0)\operatorname{nextUp}(\pm 0) は最小の正の非正規化数、nextUp⁡(−∞)\operatorname{nextUp}(-\infty) は最も小さい(負の)有限値、nextUp⁡(Ω)=+∞\operatorname{nextUp}(\Omega) = +\infty でオーバーフローフラグは立たず、invalid_operation を立てるのは signaling NaN だけです。コンテキストの精度より多くのビットを持つオペランドも受け付けます。

BinFloat::scaleb_ctx, BinFloat::logb_ctx

IEEE の scaleB と logB。

pub fn BinFloat::scaleb_ctx(Self, Int, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::logb_ctx(Self, BinaryContext) -> (Self, BinaryFlags)

x.scaleb_ctx(n, ctx) は通常のオーバーフローとアンダーフローの処理を伴う ∘(x⋅2n)\circ(x \cdot 2^n) であり、結果が正規化数の範囲を外れない限り厳密です。x.logb_ctx(ctx) は厳密な整数値としての ⌊log⁡2∣x∣⌋\lfloor \log_2 |x| \rfloor です(非正規化数の xx に対しても同様)。logB⁡(0)=−∞\operatorname{logB}(0) = -\infty で division_by_zero が立ち、logB⁡(±∞)=+∞\operatorname{logB}(\pm\infty) = +\infty であり、NaN は伝播します。

///|
test "IEEE integral, integer and neighbour operations" {
  let ctx = @bin_float.BinaryContext::binary64()
  let x = @bin_float.BinFloat::from_string("-2.5").unwrap()
  inspect(
    "\{x.floor()} \{x.ceil()} \{x.trunc()} \{x.round()} \{x.round_ties_even()}",
    content="-3p0 -1p1 -1p1 -3p0 -1p1",
  )
  let (n, flags) = x.to_int_ctx(ctx, exact=true)
  inspect("\{n.unwrap()} \{flags.inexact()}", content="-2 true")
  let (up, _) = @bin_float.BinFloat::one().next_up_ctx(ctx)
  inspect(up.to_hex(), content="0x10000000000001p-52")
  let (tiny, _) = @bin_float.BinFloat::zero().next_up_ctx(ctx)
  inspect(tiny.to_shortest_string_ctx(ctx), content="5e-324")
}

比較と順序

BinFloat::compare

すべての値について全域的な、数値的な三方比較です。

pub fn BinFloat::compare(Self, Self) -> Int
pub impl Compare for BinFloat
pub fn BinFloat::op_lt(Self, Self) -> Bool
pub fn BinFloat::op_le(Self, Self) -> Bool
pub fn BinFloat::op_gt(Self, Self) -> Bool
pub fn BinFloat::op_ge(Self, Self) -> Bool

compare は数値に従って −1-1、00、11 のいずれかを返し、−0=+0-0 = +0 として精度は無視されます。NaN には数値的な順序がないため、compare はすべての NaN を互いに等しく、かつすべての非 NaN 値より大きいものとして扱います。アボートすることはありません。結果は全前順序であり、Compare(およびソート)が必要とするのはこれですが、IEEE の比較ではありません。この比較では nan > 1 が成り立ちます。演算子 <、<=、>、>= と昇格された op_* メソッドは compare を用います。IEEE の意味論が必要な場合は、compare_checked、後述の quiet および signaling の述語、または total_order を使ってください。この選択については設計ページで説明しています。

BinFloat::compare_checked

NaN を拒否する数値比較です。

pub fn BinFloat::compare_checked(Self, Self) -> Result[Int, @arithmetic.ArithmeticError]
pub impl @arithmetic.CompareChecked for BinFloat

どちらのオペランドも NaN でなければ compare と同じ値を返し、そうでなければ unordered_comparison エラーを返します。

BinFloat::compare_quiet, BinFloat::compare_signaling

フラグを伴う 4 値関係としての IEEE の比較です。

pub fn BinFloat::compare_quiet(Self, Self) -> (@def.PartialOrder, BinaryFlags)
pub fn BinFloat::compare_signaling(Self, Self) -> (@def.PartialOrder, BinaryFlags)

関係は Less、Equal、Greater、Unordered(いずれかのオペランドが NaN)のいずれかであり、−0=+0-0 = +0 です。quiet 形式は signaling NaN に対してのみ invalid_operation を立て、signaling 形式は順序付けられないすべての比較に対してそれを立てます(IEEE 754-2019 5.11 節)。

BinFloat::equal_quiet, BinFloat::less_quiet, BinFloat::less_equal_quiet, BinFloat::unordered_quiet, BinFloat::equal_signaling, BinFloat::less_signaling, BinFloat::less_equal_signaling

IEEE の比較述語。

pub fn BinFloat::equal_quiet(Self, Self) -> (Bool, BinaryFlags)
pub fn BinFloat::less_quiet(Self, Self) -> (Bool, BinaryFlags)
pub fn BinFloat::less_equal_quiet(Self, Self) -> (Bool, BinaryFlags)
pub fn BinFloat::unordered_quiet(Self, Self) -> (Bool, BinaryFlags)
pub fn BinFloat::equal_signaling(Self, Self) -> (Bool, BinaryFlags)
pub fn BinFloat::less_signaling(Self, Self) -> (Bool, BinaryFlags)
pub fn BinFloat::less_equal_signaling(Self, Self) -> (Bool, BinaryFlags)

compareQuietEqual、compareQuietLess、compareQuietLessEqual、compareQuietUnordered、および signaling の Equal、Less、LessEqual です。それぞれ compare_quiet または compare_signaling から導かれ、そのフラグを返します。unordered_quiet 以外のすべての述語は、順序付けられない組に対して偽です。

BinFloat::total_order, BinFloat::total_order_mag, BinFloat::total_order_compare

IEEE 754 の totalOrder 関係。

pub fn BinFloat::total_order(Self, Self) -> Bool
pub fn BinFloat::total_order_mag(Self, Self) -> Bool
pub fn BinFloat::total_order_compare(Self, Self) -> Int

total_order_compare はすべての値を次のように順序付けます

−qNaN<−sNaN<−∞<negative finite<−0<+0<positive finite<+∞<+sNaN<+qNaN,-\mathrm{qNaN} < -\mathrm{sNaN} < -\infty < \text{negative finite} < -0 < +0 < \text{positive finite} < +\infty < +\mathrm{sNaN} < +\mathrm{qNaN},

同じ符号・同じ種類の NaN はペイロードによって順序付けられます(負の側では逆順)。x.total_order(y) は total_order_compare(x, y) <= 0 であり、total_order_mag は絶対値を比較します。数値的に等しく精度だけが異なる値は等しいと比較されます。これらの演算は quiet です。

BinFloat::min, BinFloat::max

NaN のオペランドを無視して、2 つの値のうち小さい方または大きい方を返します。

pub fn BinFloat::min(Self, Self) -> Self
pub fn BinFloat::max(Self, Self) -> Self

ちょうど一方のオペランドが NaN のときは、もう一方が返されます(quiet NaN に関する IEEE 754-2008 の minNum/maxNum の規約)。オペランドが compare のもとで等しい場合(たとえば −0-0 と +0+0)はレシーバが返されます。フラグは生成されません。

BinFloat::clamp, BinFloat::clamp_checked

値を [min, max] に制限します。

pub fn BinFloat::clamp(Self, min~ : Self, max~ : Self) -> Self
pub fn BinFloat::clamp_checked(Self, min~ : Self, max~ : Self) -> Result[Self, @arithmetic.ArithmeticError]

NaN のレシーバはそのまま返されます。範囲のいずれかが NaN のとき、または min > max のとき、clamp はアボートし、clamp_checked は domain_error を返します。

BinFloat::equal, BinFloat::not_equal

構造的な等価性、すなわち導出された Eq です。

pub fn BinFloat::equal(Self, Self) -> Bool
pub fn BinFloat::not_equal(Self, Self) -> Bool

BinFloat を参照してください。これは数ではなく表現を比較します。

///|
test "three different orders on BinFloat" {
  let nan = @bin_float.BinFloat::nan()
  let zero = @bin_float.BinFloat::zero()
  let neg_zero = @bin_float.BinFloat::negative_zero()
  inspect(nan.compare(zero), content="1")
  inspect(nan.compare_checked(zero) is Err(_), content="true")
  let (unordered, flags) = zero.unordered_quiet(nan)
  inspect("\{unordered} \{flags.invalid_operation()}", content="true false")
  inspect(neg_zero.compare(zero), content="0")
  inspect(neg_zero.total_order_compare(zero), content="-1")
  inspect(neg_zero == zero, content="false")
  let values = [nan, @bin_float.BinFloat::inf(@def.Sign::Positive), zero, @bin_float.BinFloat::from_int(-3)]
  values.sort()
  inspect(values.map(fn(v) { v.to_string() }).join(" "), content="-3p0 0 inf nan")
}

テキストと十六進の変換

BinFloat::to_string

格納された厳密な値を coefficient p exponent として出力します。

pub fn BinFloat::to_string(Self) -> String
pub fn BinFloat::output(Self, &Logger) -> Unit
pub impl Show for BinFloat

有限な非ゼロの値は [-]<c>p<e>(cc は十進)として出力され、c⋅2ec \cdot 2^e を意味します(たとえば 3p-1 は 1.51.5)。ゼロは 0 と -0、無限大は inf と -inf、すべての NaN は nan として出力されます。この形式は厳密で曖昧さがありませんが、十進表記ではありません。十進表記には to_shortest_string を使ってください。

BinFloat::from_string, BinFloat::from_string_ctx

十進リテラルを正しく丸めて解析します(IEEE の convertFromDecimalCharacter)。

pub fn BinFloat::from_string(String, precision? : Int) -> Result[Self, @arithmetic.ArithmeticError]
pub fn BinFloat::from_string_ctx(String, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]

受け付ける構文は [+-]digits[.digits][e[+-]digits](先頭または末尾の小数点は許可され、指数記号は e または E)と、大文字小文字を区別しない語 inf、infinity、nan、qnan、snan であり、前後の空白は無視されます。それ以外は parse_error です。厳密な十進値 D⋅10kD \cdot 10^k は、桁数や指数によらず、コンテキストのもとで 1 回だけ丸められます。オーバーフロー、アンダーフロー、inexact は算術演算と同様に報告されます。from_string(s, precision=p) は unbounded(p)(既定値 53)を用い、フラグを破棄します。

BinFloat::to_decimal_string_ctx

固定された有効十進桁数で値を整形します(IEEE の convertToDecimalCharacter)。

pub fn BinFloat::to_decimal_string_ctx(Self, Int, BinaryContext) -> (String, BinaryFlags)

出力はちょうど digits 桁(少なくとも 1 桁)の有効数字を持つ [-]d.ddd…e±x であり、コンテキストの丸め方向で正しく丸められます。非ゼロの桁が切り捨てられた場合は inexact が立ちます。コンテキストの丸め方向だけが使われます。ゼロは符号付きで 0.00…e+0 と、無限大は inf/-inf、NaN は符号付きで nan/snan と出力されます。このテキストは from_string_ctx で読み戻せます。

BinFloat::to_shortest_string, BinFloat::to_shortest_string_ctx

同じ値として読み戻せる最短の十進表記に整形します。

pub fn BinFloat::to_shortest_string(Self) -> String
pub fn BinFloat::to_shortest_string_ctx(Self, BinaryContext) -> String

to_shortest_string_ctx(x, ctx) は、from_string_ctx(_, ctx) が最近接偶数丸めのもとで xx に戻す十進数のうち、有効桁数が最少のものを返します(コンテキスト自身の丸め方向は無視されます)。その長さの候補が 2 つ読み戻せる場合は、より近い方を、次に最終桁が偶数の方を選びます。レイアウトは ECMAScript の Number#toString に従い、十進指数が [−6,21)[-6, 21) にあるときは位取り表記、それ以外は d.ddde±x です。ECMAScript と異なり、−0-0 は -0 と出力されます。BinaryContext::binary64() における binary64 の値では、結果はホストの Double の整形と一致します。to_shortest_string() は unbounded(precision()) を用いるので、from_string(text, precision=x.precision()) が x に戻す最短の文字列になります。オペランドはコンテキストで表現可能であるべきです。

BinFloat::from_hex, BinFloat::to_hex

十六進の係数で厳密な値を読み書きします。

pub fn BinFloat::from_hex(String, Int) -> Result[Self, @arithmetic.ArithmeticError]
pub fn BinFloat::to_hex(Self) -> String

構文は [+-]0x<hexdigits>p<decimal exponent> で、整数の係数に 2exponent2^{\text{exponent}} を掛けたものを意味します。0x3p-1 は 1.51.5 です。十六進の小数点はないため、C 形式の 0x1.8p0 は parse_error になります。from_hex(s, p) は最近接偶数丸めで精度 p に丸め、符号付きの nan、inf、infinity も受け付けます。to_hex は格納された係数を小文字で出力し、ゼロは 0x0p0、nan/inf は符号付きで出力します。

///|
test "decimal and hexadecimal text" {
  let tenth = @bin_float.BinFloat::from_string("0.1").unwrap()
  inspect(tenth, content="3602879701896397p-55")
  inspect(tenth.to_hex(), content="0xccccccccccccdp-55")
  inspect(tenth.to_shortest_string(), content="0.1")
  let ctx = @bin_float.BinaryContext::binary64()
  let (digits, flags) = tenth.to_decimal_string_ctx(25, ctx)
  inspect("\{digits} \{flags.inexact()}", content="1.000000000000000055511151e-1 true")
  let (single, _) = @bin_float.BinFloat::from_string_ctx("0.1", @bin_float.BinaryContext::binary32()).unwrap()
  inspect(single, content="13421773p-27")
  inspect(@bin_float.BinFloat::from_hex("0x3p-1", 53).unwrap(), content="3p-1")
}

交換エンコーディング

BinaryInterchangeFormat

IEEE 754 の 4 つの二進交換形式。

pub(all) enum BinaryInterchangeFormat {
  Binary16
  Binary32
  Binary64
  Binary128
} derive(Eq, @debug.Debug)
pub fn BinaryInterchangeFormat::equal(Self, Self) -> Bool
pub fn BinaryInterchangeFormat::not_equal(Self, Self) -> Bool
pub fn BinaryInterchangeFormat::to_repr(Self) -> @debug.Repr

BinaryInterchangeFormat::precision, BinaryInterchangeFormat::e_min, BinaryInterchangeFormat::e_max, BinaryInterchangeFormat::bias, BinaryInterchangeFormat::exponent_bits, BinaryInterchangeFormat::fraction_bits, BinaryInterchangeFormat::total_bits

形式のパラメータ。

pub fn BinaryInterchangeFormat::precision(Self) -> Int
pub fn BinaryInterchangeFormat::e_min(Self) -> Int
pub fn BinaryInterchangeFormat::e_max(Self) -> Int
pub fn BinaryInterchangeFormat::bias(Self) -> Int
pub fn BinaryInterchangeFormat::exponent_bits(Self) -> Int
pub fn BinaryInterchangeFormat::fraction_bits(Self) -> Int
pub fn BinaryInterchangeFormat::total_bits(Self) -> Int
形式total_bits kkexponent_bits wwfraction_bits p−1p-1precision ppbias =emax⁡= e_{\max}e_min =1−emax⁡= 1 - e_{\max}
Binary16165101115−14
Binary323282324127−126
Binary64641152531023−1022
Binary1281281511211316383−16382

BinaryInterchangeFormat::context

形式の BinaryContext を返します。

pub fn BinaryInterchangeFormat::context(Self, rounding? : BinaryRoundingMode, tininess? : TininessDetection) -> BinaryContext

BinaryInterchange

エンコードされた値、すなわち形式とそのビットパターンです。

pub struct BinaryInterchange {
  // private fields
} derive(Eq)
pub fn BinaryInterchange::equal(Self, Self) -> Bool
pub fn BinaryInterchange::not_equal(Self, Self) -> Bool
pub fn BinaryInterchange::format(Self) -> BinaryInterchangeFormat
pub fn BinaryInterchange::bits(Self) -> BinCoeff

等価性は形式とビットを比較するため、ペイロードの異なる NaN の 2 つのエンコーディングは異なり、±0\pm 0 も異なります。

BinaryInterchange::from_bits, BinaryInterchange::from_hex, BinaryInterchange::to_hex

エンコーディングを構築または出力します。

pub fn BinaryInterchange::from_bits(BinCoeff, BinaryInterchangeFormat) -> Self
pub fn BinaryInterchange::from_hex(String, BinaryInterchangeFormat) -> Self?
pub fn BinaryInterchange::to_hex(Self) -> String

from_bits は下位 total_bits ビットを保持します。from_hex はちょうど total_bits / 4 桁の十六進数字(省略可能な接頭辞 0x または # 付き)を必要とし、そうでなければ None を返します。to_hex は全幅までゼロ埋めした大文字の数字を出力します。

BinaryInterchange::to_bin_float

エンコーディングを厳密にデコードします。

pub fn BinaryInterchange::to_bin_float(Self) -> BinFloat

結果は形式の精度を持ちます。正規化数と非正規化数、符号付きゼロ、無限大は厳密にデコードされます。NaN は符号とペイロード(quiet ビットを除いた仮数部)を保持し、signaling NaN は signaling のままです。ホストの Float や Double は一切関与しません。

BinaryInterchange::from_bin_float, BinFloat::to_interchange

値を形式へ丸めてエンコードします。

pub fn BinaryInterchange::from_bin_float(BinFloat, BinaryInterchangeFormat, rounding? : BinaryRoundingMode, tininess? : TininessDetection) -> (Self, BinaryFlags)
pub fn BinFloat::to_interchange(Self, BinaryInterchangeFormat, rounding? : BinaryRoundingMode, tininess? : TininessDetection) -> (BinaryInterchange, BinaryFlags)

2 つは同じ演算です。形式のコンテキストで round_ctx を行い、その後エンコードします。signaling NaN は invalid_operation とともに quiet NaN としてエンコードされ、ペイロードはペイロードフィールドに切り詰められます。

///|
test "encode and decode interchange bits" {
  let b32 = @bin_float.BinaryInterchangeFormat::Binary32
  let tenth = @bin_float.BinFloat::from_string("0.1", precision=200).unwrap()
  let (nearest, flags) = tenth.to_interchange(b32)
  inspect("\{nearest.to_hex()} \{flags.inexact()}", content="3DCCCCCD true")
  let (chopped, _) = tenth.to_interchange(
    b32,
    rounding=@bin_float.BinaryRoundingMode::RoundTowardZero,
  )
  inspect(chopped.to_hex(), content="3DCCCCCC")
  let snan = @bin_float.BinaryInterchange::from_hex("7F800001", b32)
    .unwrap()
    .to_bin_float()
  let (quieted, nan_flags) = snan.to_interchange(b32)
  inspect("\{quieted.to_hex()} \{nan_flags.invalid_operation()}", content="7FC00001 true")
}

初等関数

各初等関数には 3 つの形式があります:

  • f(x) は、実装の指数範囲で x の精度(2 オペランドの場合は大きい方の精度)へ最近接偶数丸めします。
  • f_ctx(x, ctx) は ctx のもとで丸め、(value, flags) を返します。
  • try_f_ctx(x, ctx) は同じ組を Ok で返すか、@lf_arith.ArithmeticError を返します。

3 つとも同じ認証付きアルゴリズムを実行します。厳密な値の方向付き丸めによる包含区間を p+64p + 64 ビットの作業精度で求め、包含区間の両端が同じフラグで同じ値に丸められるまで、最大 12 回精密化します(各ステップで max⁡(32,w/2)\max(32, w/2) ビットを追加)。したがって、返される値は常に正しく丸められた結果 ∘(f(x))\circ(f(x)) であり、inexact も正確です。予算を使い果たした場合、try_f_ctx は certification_failure エラーを返し、その CertificationFailureDetail は演算、段階(RangeReduction または TargetRounding)、理由、最後の作業精度を示します。実数の定義域外の引数に対しては、try_f_ctx から domain_error が得られます。try でない形式は、どちらの種類のエラーも invalid_operation を伴う quiet NaN に変えます。NaN のオペランドは quiet に伝播し、極では division_by_zero とともに符号付き無限大が返されます(たとえば ln⁡0=−∞\ln 0 = -\infty、atanh⁡(1)=+∞\operatorname{atanh}(1) = +\infty)。包含区間では分離できない厳密に表現可能な結果は先に検出されます。たとえば log⁡22k=k\log_2 2^k = k、整数 nn に対する 2n2^n、sin⁡(±0)=±0\sin(\pm 0) = \pm 0、sinpi⁡(1/2)=1\operatorname{sinpi}(1/2) = 1 などです。

BinFloat::exp, BinFloat::expm1, BinFloat::exp2, BinFloat::exp10

指数関数 exe^x、ex−1e^x - 1、2x2^x、10x10^x。

pub fn BinFloat::exp(Self) -> Self
pub fn BinFloat::exp_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_exp_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::expm1(Self) -> Self
pub fn BinFloat::expm1_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_expm1_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::exp2(Self) -> Self
pub fn BinFloat::exp2_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_exp2_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::exp10(Self) -> Self
pub fn BinFloat::exp10_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_exp10_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]

R\mathbb{R} 全体で定義され、f(−∞)=0f(-\infty) = 0(expm1 では −1-1)、f(+∞)=+∞f(+\infty) = +\infty です。確実に指数範囲を超える結果はメインループの前に認証付きの log⁡2\log_2 の上下界から判定されるため、非常に大きな引数は失敗せずに正しいフラグとともにオーバーフローまたはアンダーフローします。

BinFloat::ln, BinFloat::log1p, BinFloat::log2, BinFloat::log10

対数関数 ln⁡x\ln x、ln⁡(1+x)\ln(1+x)、log⁡2x\log_2 x、log⁡10x\log_{10} x。

pub fn BinFloat::ln(Self) -> Self
pub fn BinFloat::ln_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_ln_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::log1p(Self) -> Self
pub fn BinFloat::log1p_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_log1p_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::log2(Self) -> Self
pub fn BinFloat::log2_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_log2_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::log10(Self) -> Self
pub fn BinFloat::log10_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_log10_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]

定義域は x>0x > 0(log1p では x>−1x > -1)です。境界では結果は division_by_zero を伴う −∞-\infty です。それを下回る有限の引数は domain_error であり、−∞-\infty からは invalid_operation とともに quiet NaN が得られます。

BinFloat::exp_ln

xx に等しい融合合成 ln⁡(ex)\ln(e^x)。

pub fn BinFloat::exp_ln(Self) -> Self
pub fn BinFloat::exp_ln_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_exp_ln_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]

結果は、2 回の中間丸めを経ずに xx をコンテキストへ 1 回だけ丸めたものです。現在の実装は ∣x∣≤1/8|x| \le 1/8 の有限な引数と無限大を受け付けます。それ以外の有限な引数は、引数還元の段階での certification_failure になります。

BinFloat::pow, BinFloat::rootn, BinFloat::hypot

実数べき xyx^y、nn 乗根 x1/nx^{1/n}、および x2+y2\sqrt{x^2+y^2}。

pub fn BinFloat::pow(Self, Self) -> Self
pub fn BinFloat::pow_ctx(Self, Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_pow_ctx(Self, Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::rootn(Self, Int) -> Self
pub fn BinFloat::rootn_ctx(Self, Int, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_rootn_ctx(Self, Int, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::hypot(Self, Self) -> Self
pub fn BinFloat::hypot_ctx(Self, Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_hypot_ctx(Self, Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]

pow は特殊なケースについて IEEE の pow に従います。NaN を含むすべての xx と yy に対して x±0=1x^{\pm 0} = 1 かつ 1y=11^y = 1 です。∣y∣<231|y| < 2^{31} の整数の指数は pown で、y=1/2ky = 1/2^k は rootn で処理されます。それ以外では、負の有限な底は domain_error、0y<0=+∞0^{y<0} = +\infty で division_by_zero が立ち、値は yln⁡xy \ln x の包含区間から認証されます。rootn(x, n) は実数の nn 乗根です。奇数の nn は負の xx を受け付け、偶数の nn で x<0x < 0 のときは domain_error、n=0n = 0 も domain_error です。負の nn からは x−1/nx^{-1/n} が得られ、rootn⁡(±0,n<0)=±∞\operatorname{rootn}(\pm 0, n<0) = \pm\infty で division_by_zero が立ちます。hypot はオペランドを厳密に平方し、正しく丸められた平方根を 1 回だけとります。yy が NaN であっても hypot⁡(±∞,y)=+∞\operatorname{hypot}(\pm\infty, y) = +\infty です。

BinFloat::sin, BinFloat::cos, BinFloat::tan

ラジアン単位の引数の三角関数。

pub fn BinFloat::sin(Self) -> Self
pub fn BinFloat::sin_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_sin_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::cos(Self) -> Self
pub fn BinFloat::cos_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_cos_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::tan(Self) -> Self
pub fn BinFloat::tan_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_tan_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]

引数は p+max⁡(0,⌊log⁡2∣x∣⌋+1)+96p + \max(0, \lfloor\log_2|x|\rfloor + 1) + 96 ビットで計算した π/2\pi/2 の包含区間によって還元されるため、すべての有限な入力に対して、包含区間の意味で還元は厳密です。無限大の引数は domain_error です。10610^6 を超える作業ビットを要する引数(おおよそ ∣x∣>2999,000|x| > 2^{999{,}000})は、理由 ResourceLimit の certification_failure を返します。

BinFloat::sinpi, BinFloat::cospi, BinFloat::tanpi

sin⁡(πx)\sin(\pi x)、cos⁡(πx)\cos(\pi x)、tan⁡(πx)\tan(\pi x)。

pub fn BinFloat::sinpi(Self) -> Self
pub fn BinFloat::sinpi_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_sinpi_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::cospi(Self) -> Self
pub fn BinFloat::cospi_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_cospi_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::tanpi(Self) -> Self
pub fn BinFloat::tanpi_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_tanpi_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]

周期は二進表現上で厳密に還元されるため、非常に大きな引数でも追加のコストはかかりません。整数と半整数では厳密な結果が得られます。整数 nn に対して sinpi⁡(n)=±0\operatorname{sinpi}(n) = \pm 0(符号は nn の符号)、cospi⁡(n)=±1\operatorname{cospi}(n) = \pm 1 です。1/21/2 の奇数倍では cospi は +0+0、tanpi は division_by_zero を伴う符号付き無限大です。無限大の引数は domain_error です。

BinFloat::asin, BinFloat::acos, BinFloat::atan, BinFloat::atan2

逆三角関数。

pub fn BinFloat::asin(Self) -> Self
pub fn BinFloat::asin_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_asin_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::acos(Self) -> Self
pub fn BinFloat::acos_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_acos_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::atan(Self) -> Self
pub fn BinFloat::atan_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_atan_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::atan2(Self, Self) -> Self
pub fn BinFloat::atan2_ctx(Self, Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_atan2_ctx(Self, Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]

asin と acos は [−1,1][-1, 1] 上で定義されており、その外での asin は domain_error です。atan⁡(±∞)=±π/2\operatorname{atan}(\pm\infty) = \pm\pi/2 は正しく丸められます。y.atan2(x) は [−π,π][-\pi, \pi] における点 (x,y)(x, y) の角度です。無限大のオペランドは IEEE 754 に従い(たとえば atan2⁡(+∞,−∞)=3π/4\operatorname{atan2}(+\infty, -\infty) = 3\pi/4)、atan2⁡(±0,x>0)=±0\operatorname{atan2}(\pm 0, x > 0) = \pm 0 です。

BinFloat::sinh, BinFloat::cosh, BinFloat::tanh, BinFloat::asinh, BinFloat::acosh, BinFloat::atanh

双曲線関数とその逆関数。

pub fn BinFloat::sinh(Self) -> Self
pub fn BinFloat::sinh_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_sinh_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::cosh(Self) -> Self
pub fn BinFloat::cosh_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_cosh_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::tanh(Self) -> Self
pub fn BinFloat::tanh_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_tanh_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::asinh(Self) -> Self
pub fn BinFloat::asinh_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_asinh_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::acosh(Self) -> Self
pub fn BinFloat::acosh_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_acosh_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::atanh(Self) -> Self
pub fn BinFloat::atanh_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::try_atanh_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]

acosh は x≥1x \ge 1、atanh は ∣x∣≤1|x| \le 1 を必要とし、これらの集合の外では結果は domain_error です。atanh⁡(±1)=±∞\operatorname{atanh}(\pm 1) = \pm\infty で division_by_zero が立ち、tanh⁡(±∞)=±1\operatorname{tanh}(\pm\infty) = \pm 1 です。

///|
test "elementary functions are correctly rounded" {
  let ctx = @bin_float.BinaryContext::binary64()
  let one = @bin_float.BinFloat::one()
  inspect(one.exp_ctx(ctx).0.to_shortest_string(), content="2.718281828459045")
  inspect(@bin_float.BinFloat::from_int(8).log2(), content="3p0")
  let (big, flags) = @bin_float.BinFloat::from_int(1000).exp_ctx(ctx)
  inspect("\{big} \{flags.overflow()}", content="inf true")
  match @bin_float.BinFloat::from_int(-1).try_ln_ctx(ctx) {
    Ok(_) => fail("ln(-1) has no real value")
    Err(error) => inspect(error.is_domain_error(), content="true")
  }
  let (nan, nan_flags) = @bin_float.BinFloat::from_int(-1).ln_ctx(ctx)
  inspect("\{nan} \{nan_flags.invalid_operation()}", content="nan true")
}

トレイト実装

@def.Floating

floating で共有される浮動小数点の語彙です。

pub impl @def.Floating for BinFloat

classify、sign、precision、with_precision、normalized は上記の固有メソッドです。汎用コードでは @def.is_finite、@def.is_nan、@def.is_infinite、@def.is_zero を使います。

checked トレイト

メソッドが Result を返す @lf_arith のトレイトです。

pub impl @arithmetic.SqrtChecked for BinFloat
pub impl @arithmetic.DivChecked for BinFloat
pub impl @arithmetic.CompareChecked for BinFloat
pub impl @arithmetic.PowNatChecked for BinFloat
pub impl @arithmetic.PowIntChecked for BinFloat
pub fn BinFloat::sqrt_checked(Self, @arithmetic.ArithmeticContext) -> Result[Self, @arithmetic.ArithmeticError]
pub fn BinFloat::pow_nat_checked(Self, UInt, @arithmetic.ArithmeticContext) -> Result[Self, @arithmetic.ArithmeticError]
pub fn BinFloat::pow_int_checked(Self, Int, @arithmetic.ArithmeticContext) -> Result[Self, @arithmetic.ArithmeticError]

それぞれ BinaryContext::from_arithmetic_context で ArithmeticContext を変換し、contextual 演算を実行してフラグを破棄します。sqrt_checked は負の非ゼロの引数に対して domain_error です(sqrt と同様、符号ビットが立った NaN を含みます)。DivChecked::div_checked は有限なゼロの除数に対して division_by_zero エラー、pow_int_checked はゼロの底と負の指数に対して division_by_zero エラーであり、pow_nat_checked は決して失敗しません。トレイトの div_checked(x, y, ctx) はコンテキストを受け取りますが、固有メソッドの BinFloat::div_checked は受け取りません。

contextual トレイト

診断情報付きの ArithmeticOutcome を返す @lf_arith のトレイトです。

pub impl @arithmetic.AddContextual for BinFloat
pub impl @arithmetic.SubContextual for BinFloat
pub impl @arithmetic.MulContextual for BinFloat
pub impl @arithmetic.DivContextual for BinFloat
pub impl @arithmetic.AbsContextual for BinFloat
pub impl @arithmetic.SqrtContextual for BinFloat
pub impl @arithmetic.ExpContextual for BinFloat
pub fn BinFloat::add_contextual(Self, Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]
pub fn BinFloat::sub_contextual(Self, Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]
pub fn BinFloat::mul_contextual(Self, Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]
pub fn BinFloat::div_contextual(Self, Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]
pub fn BinFloat::abs_contextual(Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]
pub fn BinFloat::sqrt_contextual(Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]
pub fn BinFloat::exp_contextual(Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]

それぞれ、変換されたコンテキストのもとで対応する *_ctx メソッド(abs では abs の後に round_ctx、exp では try_exp_ctx)を実行します。division_by_zero を伴う結果は division_by_zero エラーに、invalid_operation を伴う結果は domain_error になります。exp の認証失敗はそのまま返されます。それ以外の場合、値は ArithmeticDiagnostics とともに返され、その inexact と rounded は inexact フラグ、overflow と underflow は対応するフラグです。

Show、Debug と昇格されたメソッド

pub fn BinFloat::to_repr(Self) -> @debug.Repr

Show は to_string の厳密な c p e 形式です。Debug(debug_inspect で使われる to_repr)はすべての非公開フィールドを表示します。equal、not_equal、output、op_lt、op_le、op_gt、op_ge は型に昇格されたトレイトメソッドであり、上記のそれぞれのトレイトとともに説明されています。

公開インターフェース全体

// Generated using `moon info`, DON'T EDIT IT
package "Luna-Flow/floating/bin_float"

import {
  "Luna-Flow/arithmetic",
  "Luna-Flow/floating/def",
  "moonbitlang/core/debug",
}

// Values
pub let binary_implementation_e_max : Int

pub let binary_implementation_e_min : Int

pub let binary_precision_max : Int

pub fn sqrt_bounds_for_precision(BinFloat, Int) -> Result[(BinFloat, BinFloat), @arithmetic.ArithmeticError]

pub fn sqrt_for_precision(BinFloat, Int) -> Result[BinFloat, @arithmetic.ArithmeticError]

// Errors

// Types and methods
pub struct BinCoeff {
  // private fields
} derive(@debug.Debug)
pub fn BinCoeff::add(Self, Self) -> Self
pub fn BinCoeff::bit_and(Self, Self) -> Self
pub fn BinCoeff::bit_length(Self) -> Int
pub fn BinCoeff::bit_or(Self, Self) -> Self
pub fn BinCoeff::bit_xor(Self, Self) -> Self
pub fn BinCoeff::compare(Self, Self) -> Int
pub fn BinCoeff::ctz(Self) -> Int
pub fn BinCoeff::div_rem_checked(Self, Self) -> Result[(Self, Self), String]
pub fn BinCoeff::equal(Self, Self) -> Bool
pub fn BinCoeff::from_bytes_be(BytesView) -> Self
pub fn BinCoeff::from_uint64(UInt64) -> Self
pub fn BinCoeff::gcd(Self, Self) -> Self
pub fn BinCoeff::is_zero(Self) -> Bool
pub fn BinCoeff::mul(Self, Self) -> Self
pub fn BinCoeff::not_equal(Self, Self) -> Bool
pub fn BinCoeff::one() -> Self
pub fn BinCoeff::op_ge(Self, Self) -> Bool
pub fn BinCoeff::op_gt(Self, Self) -> Bool
pub fn BinCoeff::op_le(Self, Self) -> Bool
pub fn BinCoeff::op_lt(Self, Self) -> Bool
pub fn BinCoeff::output(Self, &Logger) -> Unit
pub fn BinCoeff::parse(String, radix? : Int) -> Result[Self, String]
pub fn BinCoeff::pow_nat(Self, UInt) -> Self
pub fn BinCoeff::shift_left(Self, Int) -> Self
pub fn BinCoeff::shift_right(Self, Int) -> Self
pub fn BinCoeff::shl(Self, Int) -> Self
pub fn BinCoeff::shr(Self, Int) -> Self
pub fn BinCoeff::square(Self) -> Self
pub fn BinCoeff::sub_checked(Self, Self) -> Result[Self, String]
pub fn BinCoeff::test_bit(Self, Int) -> Bool
pub fn BinCoeff::to_bytes_be(Self) -> Bytes
pub fn BinCoeff::to_radix_string(Self, Int) -> String
pub fn BinCoeff::to_repr(Self) -> @debug.Repr
pub fn BinCoeff::to_string(Self) -> String
pub fn BinCoeff::to_uint64(Self) -> UInt64?
pub fn BinCoeff::zero() -> Self
pub impl Add for BinCoeff
pub impl Compare for BinCoeff
pub impl Eq for BinCoeff
pub impl Mul for BinCoeff
pub impl Shl for BinCoeff
pub impl Show for BinCoeff
pub impl Shr for BinCoeff

pub struct BinFloat {
  // private fields
} derive(Eq, @debug.Debug)
pub fn BinFloat::abs(Self) -> Self
pub fn BinFloat::abs_contextual(Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]
pub fn BinFloat::acos(Self) -> Self
pub fn BinFloat::acos_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::acosh(Self) -> Self
pub fn BinFloat::acosh_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::add(Self, Self) -> Self
pub fn BinFloat::add_contextual(Self, Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]
pub fn BinFloat::add_ctx(Self, Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::asin(Self) -> Self
pub fn BinFloat::asin_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::asinh(Self) -> Self
pub fn BinFloat::asinh_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::atan(Self) -> Self
pub fn BinFloat::atan2(Self, Self) -> Self
pub fn BinFloat::atan2_ctx(Self, Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::atan_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::atanh(Self) -> Self
pub fn BinFloat::atanh_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::ceil(Self) -> Self
pub fn BinFloat::clamp(Self, min~ : Self, max~ : Self) -> Self
pub fn BinFloat::clamp_checked(Self, min~ : Self, max~ : Self) -> Result[Self, @arithmetic.ArithmeticError]
pub fn BinFloat::classify(Self) -> @arithmetic.FpClass
pub fn BinFloat::coefficient(Self) -> BinCoeff
pub fn BinFloat::compare(Self, Self) -> Int
pub fn BinFloat::compare_checked(Self, Self) -> Result[Int, @arithmetic.ArithmeticError]
pub fn BinFloat::compare_quiet(Self, Self) -> (@def.PartialOrder, BinaryFlags)
pub fn BinFloat::compare_signaling(Self, Self) -> (@def.PartialOrder, BinaryFlags)
pub fn BinFloat::copy_sign(Self, Self) -> Self
pub fn BinFloat::cos(Self) -> Self
pub fn BinFloat::cos_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::cosh(Self) -> Self
pub fn BinFloat::cosh_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::cospi(Self) -> Self
pub fn BinFloat::cospi_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::div(Self, Self) -> Self
pub fn BinFloat::div_checked(Self, Self) -> Result[Self, @arithmetic.ArithmeticError]
pub fn BinFloat::div_contextual(Self, Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]
pub fn BinFloat::div_ctx(Self, Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::equal(Self, Self) -> Bool
pub fn BinFloat::equal_quiet(Self, Self) -> (Bool, BinaryFlags)
pub fn BinFloat::equal_signaling(Self, Self) -> (Bool, BinaryFlags)
pub fn BinFloat::exp(Self) -> Self
pub fn BinFloat::exp10(Self) -> Self
pub fn BinFloat::exp10_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::exp2(Self) -> Self
pub fn BinFloat::exp2_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::exp_contextual(Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]
pub fn BinFloat::exp_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::exp_ln(Self) -> Self
pub fn BinFloat::exp_ln_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::expm1(Self) -> Self
pub fn BinFloat::expm1_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::exponent2(Self) -> Int
pub fn BinFloat::floor(Self) -> Self
pub fn BinFloat::fma(Self, Self, Self) -> Self
pub fn BinFloat::fma_ctx(Self, Self, Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::from_coefficient(BinCoeff, precision? : Int, negative? : Bool) -> Self
pub fn BinFloat::from_double(Double, precision? : Int) -> Self
pub fn BinFloat::from_float(Float, precision? : Int) -> Self
pub fn BinFloat::from_hex(String, Int) -> Result[Self, @arithmetic.ArithmeticError]
pub fn BinFloat::from_int(Int, precision? : Int) -> Self
pub fn BinFloat::from_string(String, precision? : Int) -> Result[Self, @arithmetic.ArithmeticError]
pub fn BinFloat::from_string_ctx(String, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::hypot(Self, Self) -> Self
pub fn BinFloat::hypot_ctx(Self, Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::inf(@def.Sign, precision? : Int) -> Self
pub fn BinFloat::is_negative(Self) -> Bool
pub fn BinFloat::is_negative_zero(Self) -> Bool
pub fn BinFloat::is_quiet_nan(Self) -> Bool
pub fn BinFloat::is_signaling_nan(Self) -> Bool
pub fn BinFloat::is_zero(Self) -> Bool
pub fn BinFloat::less_equal_quiet(Self, Self) -> (Bool, BinaryFlags)
pub fn BinFloat::less_equal_signaling(Self, Self) -> (Bool, BinaryFlags)
pub fn BinFloat::less_quiet(Self, Self) -> (Bool, BinaryFlags)
pub fn BinFloat::less_signaling(Self, Self) -> (Bool, BinaryFlags)
pub fn BinFloat::ln(Self) -> Self
pub fn BinFloat::ln_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::log10(Self) -> Self
pub fn BinFloat::log10_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::log1p(Self) -> Self
pub fn BinFloat::log1p_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::log2(Self) -> Self
pub fn BinFloat::log2_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::logb_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::make(BinCoeff, Int, Int, negative? : Bool, mode? : @arithmetic.RoundingMode) -> Self
pub fn BinFloat::max(Self, Self) -> Self
pub fn BinFloat::min(Self, Self) -> Self
pub fn BinFloat::mul(Self, Self) -> Self
pub fn BinFloat::mul_contextual(Self, Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]
pub fn BinFloat::mul_ctx(Self, Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::nan(precision? : Int) -> Self
pub fn BinFloat::nan_payload(Self) -> BinCoeff
pub fn BinFloat::neg(Self) -> Self
pub fn BinFloat::negative_zero(precision? : Int) -> Self
pub fn BinFloat::next_down_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::next_up_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::normalized(Self) -> Self
pub fn BinFloat::not_equal(Self, Self) -> Bool
pub fn BinFloat::one(precision? : Int) -> Self
pub fn BinFloat::op_ge(Self, Self) -> Bool
pub fn BinFloat::op_gt(Self, Self) -> Bool
pub fn BinFloat::op_le(Self, Self) -> Bool
pub fn BinFloat::op_lt(Self, Self) -> Bool
pub fn BinFloat::output(Self, &Logger) -> Unit
pub fn BinFloat::pow(Self, Self) -> Self
pub fn BinFloat::pow_ctx(Self, Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::pow_int(Self, Int) -> Result[Self, @arithmetic.ArithmeticError]
pub fn BinFloat::pow_int_checked(Self, Int, @arithmetic.ArithmeticContext) -> Result[Self, @arithmetic.ArithmeticError]
pub fn BinFloat::pow_int_ctx(Self, Int, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::pow_nat_checked(Self, UInt, @arithmetic.ArithmeticContext) -> Result[Self, @arithmetic.ArithmeticError]
pub fn BinFloat::pown(Self, Int) -> Result[Self, @arithmetic.ArithmeticError]
pub fn BinFloat::pown_ctx(Self, Int, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::precision(Self) -> Int
pub fn BinFloat::quiet_nan(payload? : BinCoeff, negative? : Bool, precision? : Int) -> Self
pub fn BinFloat::remainder(Self, Self) -> Self
pub fn BinFloat::remainder_ctx(Self, Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::rootn(Self, Int) -> Self
pub fn BinFloat::rootn_ctx(Self, Int, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::round(Self) -> Self
pub fn BinFloat::round_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::round_ties_even(Self) -> Self
pub fn BinFloat::scaleb_ctx(Self, Int, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::sign(Self) -> @def.Sign
pub fn BinFloat::signaling_nan(payload? : BinCoeff, negative? : Bool, precision? : Int) -> Self
pub fn BinFloat::sin(Self) -> Self
pub fn BinFloat::sin_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::sinh(Self) -> Self
pub fn BinFloat::sinh_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::sinpi(Self) -> Self
pub fn BinFloat::sinpi_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::sqrt(Self) -> Result[Self, @arithmetic.ArithmeticError]
pub fn BinFloat::sqrt_checked(Self, @arithmetic.ArithmeticContext) -> Result[Self, @arithmetic.ArithmeticError]
pub fn BinFloat::sqrt_contextual(Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]
pub fn BinFloat::sqrt_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::sub(Self, Self) -> Self
pub fn BinFloat::sub_contextual(Self, Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]
pub fn BinFloat::sub_ctx(Self, Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::tan(Self) -> Self
pub fn BinFloat::tan_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::tanh(Self) -> Self
pub fn BinFloat::tanh_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::tanpi(Self) -> Self
pub fn BinFloat::tanpi_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::to_decimal_string_ctx(Self, Int, BinaryContext) -> (String, BinaryFlags)
pub fn BinFloat::to_hex(Self) -> String
pub fn BinFloat::to_int64_ctx(Self, BinaryContext, exact? : Bool) -> (Int64?, BinaryFlags)
pub fn BinFloat::to_int_ctx(Self, BinaryContext, exact? : Bool) -> (Int?, BinaryFlags)
pub fn BinFloat::to_integral_exact_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::to_integral_value_ctx(Self, BinaryContext) -> (Self, BinaryFlags)
pub fn BinFloat::to_interchange(Self, BinaryInterchangeFormat, rounding? : BinaryRoundingMode, tininess? : TininessDetection) -> (BinaryInterchange, BinaryFlags)
pub fn BinFloat::to_repr(Self) -> @debug.Repr
pub fn BinFloat::to_shortest_string(Self) -> String
pub fn BinFloat::to_shortest_string_ctx(Self, BinaryContext) -> String
pub fn BinFloat::to_string(Self) -> String
pub fn BinFloat::to_uint64_ctx(Self, BinaryContext, exact? : Bool) -> (UInt64?, BinaryFlags)
pub fn BinFloat::to_uint_ctx(Self, BinaryContext, exact? : Bool) -> (UInt?, BinaryFlags)
pub fn BinFloat::total_order(Self, Self) -> Bool
pub fn BinFloat::total_order_compare(Self, Self) -> Int
pub fn BinFloat::total_order_mag(Self, Self) -> Bool
pub fn BinFloat::trunc(Self) -> Self
pub fn BinFloat::try_acos_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::try_acosh_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::try_asin_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::try_asinh_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::try_atan2_ctx(Self, Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::try_atan_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::try_atanh_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::try_cos_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::try_cosh_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::try_cospi_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::try_exp10_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::try_exp2_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::try_exp_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::try_exp_ln_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::try_expm1_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::try_hypot_ctx(Self, Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::try_ln_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::try_log10_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::try_log1p_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::try_log2_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::try_pow_ctx(Self, Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::try_rootn_ctx(Self, Int, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::try_sin_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::try_sinh_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::try_sinpi_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::try_tan_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::try_tanh_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::try_tanpi_ctx(Self, BinaryContext) -> Result[(Self, BinaryFlags), @arithmetic.ArithmeticError]
pub fn BinFloat::ulp(Self) -> Self
pub fn BinFloat::unordered_quiet(Self, Self) -> (Bool, BinaryFlags)
pub fn BinFloat::with_precision(Self, Int, @arithmetic.RoundingMode) -> Self
pub fn BinFloat::zero(precision? : Int) -> Self
pub impl @arithmetic.AbsContextual for BinFloat
pub impl @arithmetic.AddContextual for BinFloat
pub impl @arithmetic.CompareChecked for BinFloat
pub impl @arithmetic.DivChecked for BinFloat
pub impl @arithmetic.DivContextual for BinFloat
pub impl @arithmetic.ExpContextual for BinFloat
pub impl @arithmetic.MulContextual for BinFloat
pub impl @arithmetic.PowIntChecked for BinFloat
pub impl @arithmetic.PowNatChecked for BinFloat
pub impl @arithmetic.SqrtChecked for BinFloat
pub impl @arithmetic.SqrtContextual for BinFloat
pub impl @arithmetic.SubContextual for BinFloat
pub impl @def.Floating for BinFloat
pub impl Add for BinFloat
pub impl Compare for BinFloat
pub impl Div for BinFloat
pub impl Mul for BinFloat
pub impl Neg for BinFloat
pub impl Show for BinFloat
pub impl Sub for BinFloat

pub struct BinaryContext {
  // private fields
} derive(Eq, @debug.Debug)
pub fn BinaryContext::binary128(rounding? : BinaryRoundingMode, tininess? : TininessDetection) -> Self
pub fn BinaryContext::binary16(rounding? : BinaryRoundingMode, tininess? : TininessDetection) -> Self
pub fn BinaryContext::binary32(rounding? : BinaryRoundingMode, tininess? : TininessDetection) -> Self
pub fn BinaryContext::binary64(rounding? : BinaryRoundingMode, tininess? : TininessDetection) -> Self
pub fn BinaryContext::e_max(Self) -> Int?
pub fn BinaryContext::e_min(Self) -> Int?
pub fn BinaryContext::equal(Self, Self) -> Bool
pub fn BinaryContext::from_arithmetic_context(@arithmetic.ArithmeticContext) -> Self
pub fn BinaryContext::new(Int, rounding? : BinaryRoundingMode, e_min? : Int, e_max? : Int, tininess? : TininessDetection) -> Self
pub fn BinaryContext::not_equal(Self, Self) -> Bool
pub fn BinaryContext::precision(Self) -> Int
pub fn BinaryContext::rounding(Self) -> BinaryRoundingMode
pub fn BinaryContext::tininess(Self) -> TininessDetection
pub fn BinaryContext::to_repr(Self) -> @debug.Repr
pub fn BinaryContext::try_new(Int, rounding? : BinaryRoundingMode, e_min? : Int, e_max? : Int, tininess? : TininessDetection) -> Result[Self, @arithmetic.ArithmeticError]
pub fn BinaryContext::unbounded(Int, rounding? : BinaryRoundingMode) -> Self

pub struct BinaryFlags {
  // private fields
} derive(Eq, @debug.Debug)
pub fn BinaryFlags::combine(Self, Self) -> Self
pub fn BinaryFlags::division_by_zero(Self) -> Bool
pub fn BinaryFlags::equal(Self, Self) -> Bool
pub fn BinaryFlags::inexact(Self) -> Bool
pub fn BinaryFlags::invalid_operation(Self) -> Bool
pub fn BinaryFlags::new() -> Self
pub fn BinaryFlags::not_equal(Self, Self) -> Bool
pub fn BinaryFlags::overflow(Self) -> Bool
pub fn BinaryFlags::to_repr(Self) -> @debug.Repr
pub fn BinaryFlags::to_testfloat_bits(Self) -> Int
pub fn BinaryFlags::underflow(Self) -> Bool

pub struct BinaryInterchange {
  // private fields
} derive(Eq)
pub fn BinaryInterchange::bits(Self) -> BinCoeff
pub fn BinaryInterchange::equal(Self, Self) -> Bool
pub fn BinaryInterchange::format(Self) -> BinaryInterchangeFormat
pub fn BinaryInterchange::from_bin_float(BinFloat, BinaryInterchangeFormat, rounding? : BinaryRoundingMode, tininess? : TininessDetection) -> (Self, BinaryFlags)
pub fn BinaryInterchange::from_bits(BinCoeff, BinaryInterchangeFormat) -> Self
pub fn BinaryInterchange::from_hex(String, BinaryInterchangeFormat) -> Self?
pub fn BinaryInterchange::not_equal(Self, Self) -> Bool
pub fn BinaryInterchange::to_bin_float(Self) -> BinFloat
pub fn BinaryInterchange::to_hex(Self) -> String

pub(all) enum BinaryInterchangeFormat {
  Binary16
  Binary32
  Binary64
  Binary128
} derive(Eq, @debug.Debug)
pub fn BinaryInterchangeFormat::bias(Self) -> Int
pub fn BinaryInterchangeFormat::context(Self, rounding? : BinaryRoundingMode, tininess? : TininessDetection) -> BinaryContext
pub fn BinaryInterchangeFormat::e_max(Self) -> Int
pub fn BinaryInterchangeFormat::e_min(Self) -> Int
pub fn BinaryInterchangeFormat::equal(Self, Self) -> Bool
pub fn BinaryInterchangeFormat::exponent_bits(Self) -> Int
pub fn BinaryInterchangeFormat::fraction_bits(Self) -> Int
pub fn BinaryInterchangeFormat::not_equal(Self, Self) -> Bool
pub fn BinaryInterchangeFormat::precision(Self) -> Int
pub fn BinaryInterchangeFormat::to_repr(Self) -> @debug.Repr
pub fn BinaryInterchangeFormat::total_bits(Self) -> Int

pub(all) enum BinaryRoundingMode {
  RoundTiesToEven
  RoundTiesToAway
  RoundTowardZero
  RoundTowardPositive
  RoundTowardNegative
  RoundAwayFromZero
} derive(Eq, @debug.Debug)
pub fn BinaryRoundingMode::equal(Self, Self) -> Bool
pub fn BinaryRoundingMode::from_arithmetic(@arithmetic.RoundingMode) -> Self
pub fn BinaryRoundingMode::not_equal(Self, Self) -> Bool
pub fn BinaryRoundingMode::to_arithmetic(Self) -> @arithmetic.RoundingMode?
pub fn BinaryRoundingMode::to_repr(Self) -> @debug.Repr

pub(all) enum TininessDetection {
  BeforeRounding
  AfterRounding
} derive(Eq, @debug.Debug)
pub fn TininessDetection::equal(Self, Self) -> Bool
pub fn TininessDetection::not_equal(Self, Self) -> Bool
pub fn TininessDetection::to_repr(Self) -> @debug.Repr

// Type aliases

// Traits