decimal API

Luna-Flow/floating/decimal 是 floating 中的 IEEE 754-2019 十进制浮点包。Decimal 是任意精度的十进制值,保留其量子(quantum,即指数)、零的符号以及 NaN 的载荷;DecimalContext 确定精度、舍入、指数范围、钳制(clamping)与微小性(tininess);每个上下文运算都返回舍入后的值及其引发的 DecimalFlags。该包还能以 DPD 和 BID 两种方式编码与解码 decimal32/64/128 交换格式,并以经过认证的舍入计算初等函数。

decimal 教程介绍常见任务,decimal 设计解释算术模型、编码、舍入与认证。支持 IEEE 声明的有限证据记录在 decimal 符合性中。粘滞的 General Decimal Arithmetic 状态与陷阱(trap)位于独立的 decimal_gda 包中;decimal_checked 则累积一串 Decimal 运算的标志。

下文记号:有限值为 (−1)s⋅c⋅10q(-1)^s \cdot c \cdot 10^{q},其中符号为 ss,非负整数系数为 cc,指数(量子)为 qq;pp 为上下文精度,emax⁡e_{\max} 与 emin⁡e_{\min} 为上下文对调整后指数 q+digits⁡(c)−1q + \operatorname{digits}(c) - 1 的限制,Etiny=emin⁡−p+1E_{\text{tiny}} = e_{\min} - p + 1 为次正规数的最小指数。

值与表示

Decimal

Decimal 是不可变的十进制浮点值。

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

Decimal 是以下之一:有限值 (−1)sc 10q(-1)^s c\,10^q(包括 ±0\pm 0)、±∞\pm\infty,或带符号与非负整数载荷的静默 NaN 或信号 NaN。每个值还带有一个工作精度 precision,供普通运算符以及没有上下文参数的转换使用。字段是私有的;请使用下面的观察函数。数学值相同但指数不同的两个值(例如 1.2 与 1.20)是同一*同值类(cohort)*的不同成员:它们在数值上比较相等,但可以通过 quantum、same_quantum、compare_total、格式化以及交换编码加以区分。

派生的 Debug 实现被提升为 Decimal::to_repr;参见 trait 实现。

Decimal::precision, coefficient, magnitude, exponent10, quantum

这些观察函数返回值的存储表示。

pub fn Decimal::precision(Self) -> Int
pub fn Decimal::coefficient(Self) -> @bigint.BigInt
pub fn Decimal::magnitude(Self) -> @bigint.BigInt
pub fn Decimal::exponent10(Self) -> Int
pub fn Decimal::quantum(Self) -> Int

precision 是值中存储的工作精度(至少为 1)。coefficient 和 magnitude 都返回非负系数 cc;对 NaN 返回载荷,对无穷返回 0。符号从不属于系数:请使用 is_negative。exponent10 和 quantum 都返回存储的指数 qq;对特殊值为 0。

///|
test "decimal representation observers" {
  let x = @decimal.Decimal::from_string("-12.300").unwrap()
  inspect(x.coefficient(), content="12300")
  inspect(x.quantum(), content="-3")
  inspect(x.is_negative(), content="true")
  inspect(x.precision(), content="34")
}

Decimal::sign, is_negative, is_signed

这些观察函数报告值的符号。

pub fn Decimal::sign(Self) -> @def.Sign
pub fn Decimal::is_negative(Self) -> Bool
pub fn Decimal::is_signed(Self) -> Bool

sign 对两个零以及所有 NaN 返回 @def.Sign::Zero,其余情况返回 Negative/Positive。is_negative 与 is_signed 是同一个谓词:它们返回存储的符号位,因此对 −0-0、−∞-\infty 以及负 NaN 都为 true。

Decimal::classify, class_name

classify 返回值的粗略类别;class_name 返回某上下文下的 General Decimal Arithmetic 类别字符串。

pub fn Decimal::classify(Self) -> @arithmetic.FpClass
pub fn Decimal::class_name(Self, DecimalContext) -> String

classify 返回 Finite、Infinity 或 NaN。class_name 返回 "sNaN"、"NaN"、"-Infinity"、"+Infinity"、"-Zero"、"+Zero"、"-Subnormal"、"+Subnormal"、"-Normal" 或 "+Normal" 之一;正规/次正规的划分使用上下文的 emin⁡e_{\min}。

谓词

这些函数检测值的类别。

pub fn Decimal::is_finite(Self) -> Bool
pub fn Decimal::is_infinite(Self) -> Bool
pub fn Decimal::is_nan(Self) -> Bool
pub fn Decimal::is_zero(Self) -> Bool
pub fn Decimal::is_negative_zero(Self) -> Bool
pub fn Decimal::is_quiet_nan(Self) -> Bool
pub fn Decimal::is_qnan(Self) -> Bool
pub fn Decimal::is_signaling_nan(Self) -> Bool
pub fn Decimal::is_snan(Self) -> Bool
pub fn Decimal::is_canonical(Self) -> Bool
pub fn Decimal::is_normal(Self, DecimalContext) -> Bool
pub fn Decimal::is_subnormal(Self, DecimalContext) -> Bool

is_qnan 和 is_snan 是 is_quiet_nan 与 is_signaling_nan 的 General Decimal Arithmetic 写法。is_canonical 总是返回 true:Decimal 不存在非规范形式;非规范的编码是 DecimalInterchange 的性质。在某上下文下,若值有限、非零且调整后指数至少为 emin⁡e_{\min},则它是正规的;若值有限、非零且调整后指数小于 emin⁡e_{\min},则它是次正规的。零、无穷与 NaN 两者都不是。

Decimal::nan_payload, get_payload, set_payload, set_payload_signaling

这些函数读取并替换 NaN 的载荷。

pub fn Decimal::nan_payload(Self) -> @bigint.BigInt
pub fn Decimal::get_payload(Self) -> @bigint.BigInt
pub fn Decimal::set_payload(Self, @bigint.BigInt) -> Self
pub fn Decimal::set_payload_signaling(Self, @bigint.BigInt) -> Self

nan_payload 和 get_payload 返回 NaN 的载荷,对其他所有值返回 0。set_payload 返回带给定载荷(取其绝对值)且保持原符号的静默 NaN;set_payload_signaling 返回信号 NaN。二者对非 NaN 参数都原样返回。

构造与转换

Decimal::make

make 由带符号的整数系数和指数构建有限值,并将其舍入到某个精度。

pub fn Decimal::make(@bigint.BigInt, Int, Int, mode? : @arithmetic.RoundingMode) -> Self

Decimal::make(c, q, p, mode~) 表示 c⋅10qc \cdot 10^{q};符号取自 c。首先去除尾随零,若系数更长,则以 mode(默认 ToNearestEven)舍入到 p 位,然后再次去除尾随零。因此结果总是其同值类中的约简成员,且 make(0, q, p) 是指数为 0 的 +0+0。不施加任何指数范围。

Decimal::zero, negative_zero, one, inf, nan, quiet_nan, signaling_nan

这些构造函数构建特殊值与单位值。

pub fn Decimal::zero(precision? : Int) -> Self
pub fn Decimal::negative_zero(precision? : Int) -> Self
pub fn Decimal::one(precision? : Int) -> Self
pub fn Decimal::inf(@def.Sign, precision? : Int) -> Self
pub fn Decimal::nan(precision? : Int) -> Self
pub fn Decimal::quiet_nan(payload? : @bigint.BigInt, negative? : Bool, precision? : Int) -> Self
pub fn Decimal::signaling_nan(payload? : @bigint.BigInt, negative? : Bool, precision? : Int) -> Self

默认精度为 34。zero、negative_zero 和 one 的指数为 0。inf(sign) 对 Negative 为 −∞-\infty,否则为 +∞+\infty。nan 是载荷为 0 的正静默 NaN;quiet_nan 和 signaling_nan 默认载荷为 0、符号为正。

Decimal::from_int, from_bigint

这些构造函数转换整数。

pub fn Decimal::from_int(Int, precision? : Int) -> Self
pub fn Decimal::from_bigint(@bigint.BigInt, precision? : Int) -> Self

二者都是采用默认精度 34 的 make(n, 0, precision):结果是约简的(from_int(1000) 为 1E+3,指数为 3),位数超过 precision 的整数按半值取偶(half-even)舍入。

Decimal::from_double, from_float

这些构造函数转换二进制浮点数。

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

每个有限 Double 都是二进有理数 m⋅2km \cdot 2^{k},因而当 k<0k<0 时具有有限十进制展开 m⋅5−k⋅10km \cdot 5^{-k} \cdot 10^{k};转换会构造这一精确展开,并按半值取偶舍入到 precision 位(默认 34)。带符号的零与无穷得以保留;每个 NaN 都变为载荷为 0、符号与输入相同的静默 NaN。from_float 先扩展为 Double,这一步是精确的。

Decimal::from_bin_float, to_bin_float

这些函数在 Decimal 与二进制 BinFloat 之间转换。

pub fn Decimal::from_bin_float(@bin_float.BinFloat, precision? : Int) -> Self
pub fn Decimal::to_bin_float(Self, precision? : Int, mode? : @arithmetic.RoundingMode) -> @bin_float.BinFloat

只要 x 的十进制展开能容纳于 precision 位十进制数字(默认:x 的精度),from_bin_float(x, precision~) 就是精确的,否则按半值取偶舍入;二进制零变为 +0+0,NaN 变为载荷为 0 的静默 NaN。to_bin_float(precision~, mode~) 以 mode(默认 ToNearestEven)将精确的十进制值舍入为 precision 位(默认:该十进制值的精度字段)的 BinFloat。大多数十进制小数都不是二进有理数,因此这一方向通常不精确;分别以 TowardNegative 和 TowardPositive 转换可得到该十进制值的二进制包络。零映射为 +0+0,NaN 载荷不予保留。

Decimal::from_nat, from_integral

这些函数转换任意 Luna-Flow 整数类型。

pub fn[S : @luna-generic.Nat] Decimal::from_nat(S) -> Self
pub fn[S : @luna-generic.Integral] Decimal::from_integral(S) -> Self

它们通过 Integral::normalize 将参数规范化为 BigInt,并以精度 34 返回 from_bigint(n).normalized()。它们是 NatHomomorphism 与 IntegralHomomorphism 的实现。

解析与格式化

Decimal::parse, from_string

parse 将十进制文本转换为 Decimal,同时保留其量子。

pub fn Decimal::parse(String, precision? : Int) -> Result[Self, @arithmetic.ArithmeticError]
pub fn Decimal::from_string(String, precision? : Int) -> Self?

可接受的语法为:可选符号、带可选小数点的数字、带可选符号的可选指数 E/e;或者 Inf、Infinity、NaN、sNaN 之一(不区分大小写),NaN 后面还可跟可选的十进制载荷数字。若有效数字能容纳于 precision(默认 34),则文本中的指数被精确保留:"1.2300" 的系数为 12300、指数为 −4-4,"0.00" 是指数为 −2-2 的 +0+0。更长的系数按半值取偶舍入到 precision 位并约简。不施加任何指数范围。无效文本使 parse 返回 Err(parse_error),使 from_string 返回 None。

Decimal::from_string_ctx

from_string_ctx 在上下文下转换文本并报告转换标志。

pub fn Decimal::from_string_ctx(String, DecimalContext) -> (Self, DecimalFlags)

语法与 parse 相同。值被舍入到上下文精度(引发 rounded,若丢弃了非零数字还会引发 inexact),按指数范围检查(上溢、次正规、下溢、钳制),并在设置了 clamp 时进行折叠(fold-down)。若 NaN 载荷的位数超过上下文允许的位数(设置 clamp 时为精度 −1-1 位,否则为精度位),则视为语法错误。无效文本返回仅设置了 conversion_syntax 标志的静默 NaN。在非扩展上下文中,Inf 与 NaN 写法属于转换语法错误。

///|
test "decimal from_string_ctx rounds and flags" {
  let ctx = @decimal.DecimalContext::decimal32()
  let (x, flags) = @decimal.Decimal::from_string_ctx("3.14159265", ctx)
  inspect(x, content="3.141593")
  inspect(flags.rounded && flags.inexact, content="true")
  let (bad, bad_flags) = @decimal.Decimal::from_string_ctx("1..2", ctx)
  inspect(bad.is_nan(), content="true")
  inspect(bad_flags.conversion_syntax, content="true")
}

Decimal::to_sci_string, to_eng_string

这些函数对文本操作数实现 General Decimal Arithmetic 的 to-scientific-string 与 to-engineering-string 转换。

pub fn Decimal::to_sci_string(String, DecimalContext) -> (String, DecimalFlags)
pub fn Decimal::to_eng_string(String, DecimalContext) -> (String, DecimalFlags)

二者都接受文本,用 from_string_ctx 转换后格式化结果。科学记数形式在指数为正或调整后指数小于 −6-6 时,用指数 E±n 书写系数,否则写成普通数字;工程记数形式使用 3 的倍数作为指数。特殊值写作 Infinity、-Infinity、NaN、sNaN,带载荷时如 NaN7。标志即转换所产生的标志。

Decimal::to_string, output

to_string 在无上下文的情况下以科学记数法格式化值。

pub fn Decimal::to_string(Self) -> String
pub fn Decimal::output(Self, &Logger) -> Unit

有限值使用 to_sci_string 的科学记数字符串规则,因此尾随零和指数均可见:1.20、1E+3、1.2E-7。特殊值以小写书写:inf、-inf、nan、snan、-nan12。output 将相同文本写入 logger;二者都来自 Show 实现。

上下文

DecimalContext

DecimalContext 是一组不可变的算术参数。

pub struct DecimalContext {
  // private fields
} derive(Eq)

上下文包含精度 pp、共享的 Luna-Flow rounding 模式、十进制舍入模式(decimal_rounding,即算术实际使用的模式)、调整后指数的限制 emin⁡≤emax⁡e_{\min} \le e_{\max}、clamp 开关、extended 开关以及微小性规则。任何运算都不读取环境状态:每个上下文运算都以参数形式接收其上下文。

DecimalContext::new, try_new

这些构造函数由命名参数构建上下文。

pub fn DecimalContext::new(precision? : Int, rounding? : @arithmetic.RoundingMode, decimal_rounding? : DecimalRoundingMode, e_min? : Int, e_max? : Int, clamp? : Bool, extended? : Bool, tininess? : DecimalTininessDetection) -> Self
pub fn DecimalContext::try_new(precision? : Int, rounding? : @arithmetic.RoundingMode, decimal_rounding? : DecimalRoundingMode, e_min? : Int, e_max? : Int, clamp? : Bool, extended? : Bool, tininess? : DecimalTininessDetection) -> Result[Self, @arithmetic.ArithmeticError]
参数默认值含义
precision34系数位数 pp
roundingToNearestEven共享舍入模式
decimal_rounding由 rounding 推出算术所用的舍入模式
e_min, e_max−999 999 999-999\,999\,999, 999 999 999999\,999\,999调整后指数的范围
clampfalse将大指数折叠到 emax⁡−p+1e_{\max}-p+1
extendedtrueIEEE/扩展算术;false 选择 GDA 子集
tininessAfterRounding结果何时算作微小

省略 decimal_rounding 时,它取 DecimalRoundingMode::from_arithmetic(rounding);若要使用 HalfUp、HalfDown 或 ZeroFiveUp,请显式传入。new 在 precision <= 0 或 e_min > e_max 时中止;try_new 则返回 Err(domain_error)。

子集模式(extended=false)重现经典的 decNumber 子集:长于 pp 位的操作数先被舍入(引发 lost_digits),零结果丢失其符号和指数,特殊值文本被拒绝。它是为了兼容 General Decimal Arithmetic 测试而存在的。

DecimalContext::decimal32, decimal64, decimal128, exact

这些构造函数返回交换格式的上下文以及一个精确的工作上下文。

pub fn DecimalContext::decimal32() -> Self
pub fn DecimalContext::decimal64() -> Self
pub fn DecimalContext::decimal128() -> Self
pub fn DecimalContext::exact() -> Self
上下文ppemin⁡e_{\min}emax⁡e_{\max}clamp
decimal327−95-9596是
decimal6416−383-383384是
decimal12834−6143-61436144是

三者都使用 ToNearestEven(HalfEven)、扩展算术以及舍入后微小性判定。exact() 的精度为 0,表示“无限”:结果保留所有数字,不按精度进行舍入;其指数范围为默认范围。这是获得精度 0 的唯一途径。

DecimalContext::from_arithmetic_context

from_arithmetic_context 转换共享的 Luna-Flow 上下文。

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

精度、舍入与 clamp 被复制;缺失的 e_min 或 e_max 变为 ∓999 999 999\mp 999\,999\,999。结果为扩展上下文,并采用舍入后微小性判定。contextual 与 checked 的 trait 实现都使用这一转换。

DecimalContext::precision, rounding, decimal_rounding, e_min, e_max, clamp, extended, tininess

这些访问函数返回上下文的字段。

pub fn DecimalContext::precision(Self) -> Int
pub fn DecimalContext::rounding(Self) -> @arithmetic.RoundingMode
pub fn DecimalContext::decimal_rounding(Self) -> DecimalRoundingMode
pub fn DecimalContext::e_min(Self) -> Int
pub fn DecimalContext::e_max(Self) -> Int
pub fn DecimalContext::clamp(Self) -> Bool
pub fn DecimalContext::extended(Self) -> Bool
pub fn DecimalContext::tininess(Self) -> DecimalTininessDetection

只有 exact() 的 precision 为 0。

DecimalContext::with_rounding, with_tininess, ieee754, is754version2019

这些函数派生上下文或描述其所遵循的标准。

pub fn DecimalContext::with_rounding(Self, @arithmetic.RoundingMode) -> Self
pub fn DecimalContext::with_tininess(Self, DecimalTininessDetection) -> Self
pub fn DecimalContext::ieee754(Self) -> Self
pub fn DecimalContext::is754version2019(Self) -> Bool

with_rounding 替换两个舍入字段(十进制模式变为 from_arithmetic(rounding))。with_tininess 替换微小性规则。ieee754 原样返回上下文:每个上下文都已遵循本包的 IEEE 754-2019 语义。is754version2019 总是返回 true。

DecimalContext::equal, not_equal

这些函数逐字段比较上下文。

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

舍入模式与微小性

DecimalRoundingMode

DecimalRoundingMode 列出八种十进制舍入方向。

pub(all) enum DecimalRoundingMode {
  HalfEven
  HalfUp
  HalfDown
  Down
  Ceiling
  Floor
  Up
  ZeroFiveUp
}
pub fn DecimalRoundingMode::equal(Self, Self) -> Bool
pub fn DecimalRoundingMode::not_equal(Self, Self) -> Bool

设 x>0x>0 严格位于两个相邻可表示系数 cc 与 c+1c+1 之间(以末位单位计)。Down 返回 cc,Up 返回 c+1c+1;Ceiling 和 Floor 分别向 +∞+\infty 和 −∞-\infty 舍入(因此依赖于符号);HalfEven、HalfUp 和 HalfDown 返回两者中较近的一个,恰好处于中点时分别取偶系数、远离零、趋向零;ZeroFiveUp 在 cc 的末位数字为 0 或 5 时返回 c+1c+1,否则返回 cc。IEEE 754 将 HalfEven 称为 roundTiesToEven,HalfUp 称为 roundTiesToAway,Down 称为 roundTowardZero,Ceiling 称为 roundTowardPositive,Floor 称为 roundTowardNegative。

DecimalRoundingMode::from_arithmetic, to_arithmetic

这些函数在十进制模式与共享的 @arithmetic.RoundingMode 之间映射。

pub fn DecimalRoundingMode::from_arithmetic(@arithmetic.RoundingMode) -> Self
pub fn DecimalRoundingMode::to_arithmetic(Self) -> @arithmetic.RoundingMode?
@arithmetic.RoundingModeDecimalRoundingMode
ToNearestEvenHalfEven
TowardZeroDown
TowardPositiveCeiling
TowardNegativeFloor
AwayFromZeroUp

to_arithmetic 对 HalfUp、HalfDown 和 ZeroFiveUp 返回 None,因为共享枚举中没有这些模式。

DecimalTininessDetection

DecimalTininessDetection 决定非零结果何时为微小。

pub(all) enum DecimalTininessDetection {
  BeforeRounding
  AfterRounding
}
pub fn DecimalTininessDetection::equal(Self, Self) -> Bool
pub fn DecimalTininessDetection::not_equal(Self, Self) -> Bool

BeforeRounding 在精确结果的调整后指数小于 emin⁡e_{\min} 时判定结果微小;AfterRounding 则使用在无界指数下舍入到 pp 位后的结果进行判定。微小结果会引发 subnormal,若同时不精确还会引发 underflow。

状态标志

DecimalFlags

DecimalFlags 记录一次运算所引发的条件。

pub struct DecimalFlags {
  inexact : Bool
  rounded : Bool
  lost_digits : Bool
  invalid_operation : Bool
  division_by_zero : Bool
  overflow : Bool
  underflow : Bool
  subnormal : Bool
  clamped : Bool
  conversion_syntax : Bool
  division_impossible : Bool
  division_undefined : Bool
  invalid_context : Bool
} derive(Eq)
字段引发条件
inexact结果与精确结果不同
rounded丢弃了数字,即使它们全为零
lost_digits子集模式下长于 pp 位的操作数丢失了非零数字
invalid_operation运算无效(信号 NaN、∞−∞\infty-\infty、0×∞0\times\infty、无效的 quantize、定义域错误)
division_by_zero有限操作数产生精确的无穷结果(x/0x/0、log⁡0\log 0)
overflow舍入后结果的调整后指数超过 emax⁡e_{\max}
underflow结果微小且不精确
subnormal结果微小
clamped为适配而改变了指数(折叠或零指数钳制)
conversion_syntax文本无法解析
division_impossible整数商需要多于 pp 位数字
division_undefined0/00/0(与 invalid_operation 一同引发)
invalid_context上下文超出初等函数所支持的范围

字段是公开且只读的;标志从不隐式累积。

DecimalFlags::new, combine, contains, has_error

这些函数创建、合并与查询标志集合。

pub fn DecimalFlags::new() -> Self
pub fn DecimalFlags::combine(Self, Self) -> Self
pub fn DecimalFlags::contains(Self, DecimalSignal) -> Bool
pub fn DecimalFlags::has_error(Self) -> Bool
pub fn DecimalFlags::equal(Self, Self) -> Bool
pub fn DecimalFlags::not_equal(Self, Self) -> Bool

new 的所有标志均为清除状态。combine 是逐字段的 OR,因此满足结合律、交换律和幂等律,并以 new() 为单位元。contains 读取由 DecimalSignal 指定的标志。has_error 为 invalid_operation∨division_by_zero∨division_undefined∨division_impossible∨invalid_context\text{invalid\_operation} \lor \text{division\_by\_zero} \lor \text{division\_undefined} \lor \text{division\_impossible} \lor \text{invalid\_context};它不包括 conversion_syntax、overflow 或 underflow。

///|
test "decimal flags accumulate by combine" {
  let ctx = @decimal.DecimalContext::decimal64()
  let one = @decimal.Decimal::one()
  let three = @decimal.Decimal::from_int(3)
  let (third, f1) = one.div_ctx(three, ctx)
  let (_, f2) = one.div_ctx(@decimal.Decimal::zero(), ctx)
  let all = f1.combine(f2)
  inspect(third, content="0.3333333333333333")
  inspect(all.contains(@decimal.DecimalSignal::Inexact), content="true")
  inspect(all.division_by_zero, content="true")
  inspect(all.has_error(), content="true")
}

DecimalSignal

DecimalSignal 指定 DecimalFlags 中的一个标志。

pub(all) enum DecimalSignal {
  ConversionSyntax
  DivisionByZero
  DivisionImpossible
  DivisionUndefined
  InvalidContext
  InvalidOperation
  Overflow
  Underflow
  Subnormal
  Inexact
  Rounded
  Clamped
  LostDigits
}
pub fn DecimalSignal::equal(Self, Self) -> Bool
pub fn DecimalSignal::not_equal(Self, Self) -> Bool

每个构造子对应同名的字段。

无上下文的普通运算

本组中的运算符和函数既不接受上下文,也不返回标志。它们便于进行精确计算,以及编写基于 Luna-Flow 代数 trait 的泛型代码;只要舍入、指数范围或标志有影响,就请使用上下文算术。

Decimal::add, sub, mul, div, neg

这些函数即算术运算符 +、-、*、/ 以及一元 -。

pub fn Decimal::add(Self, Self) -> Self
pub fn Decimal::sub(Self, Self) -> Self
pub fn Decimal::mul(Self, Self) -> Self
pub fn Decimal::div(Self, Self) -> Self
pub fn Decimal::neg(Self) -> Self

结果精度为操作数精度字段的 max⁡(pa,pb)\max(p_a, p_b)。

  • add/sub 计算精确和,按半值取偶舍入到该精度,并返回同值类中的约简成员:1.20 + 3.40 为 4.6。
  • mul 返回指数为 qa+qbq_a+q_b 的精确乘积,且不进行舍入:1.25 * 2.50 为 3.1250,系数可能比精度字段更长。
  • div 将商按半值取偶舍入到该精度并约简。商的计算会带几位保护位,然后再次舍入,因此在少数情况下它与正确舍入的结果相差一个末位单位;div_ctx 只舍入一次。
  • neg 翻转每个值的符号位,包括零和 NaN。

特殊值:NaN 操作数产生一个静默 NaN,其符号和载荷取自第一个 NaN;∞−∞\infty-\infty、0×∞0\times\infty、0/00/0 和 ∞/∞\infty/\infty 产生正 NaN;x/0x/0 产生带符号的无穷;有限值/∞/\infty 产生 +0+0。不施加任何指数范围。精确抵消得到 +0+0;两个负零之和为 −0-0。

///|
test "decimal plain operators" {
  let a = @decimal.Decimal::from_string("1.20").unwrap()
  let b = @decimal.Decimal::from_string("3.40").unwrap()
  inspect(a + b, content="4.6")
  inspect(a * b, content="4.0800")
  inspect(a - b, content="-2.2")
  inspect(-a, content="-1.20")
  inspect(@decimal.Decimal::one() / @decimal.Decimal::from_int(8), content="0.125")
}

Decimal::abs, copy, copy_abs, copy_negate, copy_sign

这些函数只改变符号位。

pub fn Decimal::abs(Self) -> Self
pub fn Decimal::copy(Self) -> Self
pub fn Decimal::copy_abs(Self) -> Self
pub fn Decimal::copy_negate(Self) -> Self
pub fn Decimal::copy_sign(Self, Self) -> Self

它们从不舍入,从不引发标志,并保持指数、载荷与 NaN 种类不变。abs 和 copy_abs 清除符号,copy_negate 翻转符号,copy_sign 复制第二个操作数的符号位,copy 返回其参数。

Decimal::normalized, trim, with_precision

这些函数改变同值类成员或精度字段。

pub fn Decimal::normalized(Self) -> Self
pub fn Decimal::trim(Self) -> Self
pub fn Decimal::with_precision(Self, Int, @arithmetic.RoundingMode) -> Self

normalized 返回同值类中的约简成员(去除所有尾随零,零的指数为 0),若系数更长则按半值取偶舍入到该值自身的精度。trim 去除小数部分的尾随零:指数为负时在指数 0 处停止(12.300 变为 12.3,1200 保持 1200),指数为正时全部去除(1.20E+3 变为 1.2E+3);零的指数变为 0。with_precision(p, mode) 以 mode 将有限值舍入到 p 位,约简后将 p 存为精度字段;特殊值只获得新的精度字段。三者都不产生标志。

Decimal::div_checked, sqrt

这些函数执行除法和求平方根,并以 Result 报告定义域错误。

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

div_checked(a, b) 即 DecimalContext::new(precision=max(p_a, p_b)) 下的 div_ctx;对 x/0x/0 返回 Err(division_by_zero),对无效除法返回 Err(domain_error)。sqrt 即 DecimalContext::new(precision=p) 下的 sqrt_ctx,对负的非零操作数返回 Err(domain_error)。二者都按半值取偶正确舍入。

上下文算术

本组中的每个函数都接受一个 DecimalContext 并返回 (result, flags)。结果是将精确结果以上下文的十进制舍入模式一次性舍入到上下文精度,再按指数范围检查:上溢得到依赖于舍入模式的结果(见设计页面),微小结果被舍入到次正规网格 10Etiny10^{E_{\text{tiny}}},并且在设置 clamp 时,大指数被折叠到 emax⁡−p+1e_{\max}-p+1。当精确结果可以容纳时,指数取该运算的首选指数,因此同值类携带了信息。NaN 操作数以静默 NaN 传播,其符号和载荷取自第一个 NaN(载荷截取为其低 pp 位);任何信号 NaN 操作数都会引发 invalid_operation。

Decimal::add_ctx, sub_ctx, mul_ctx, div_ctx

这些函数是正确舍入的算术运算。

pub fn Decimal::add_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::sub_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::mul_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::div_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)

首选指数:加法与减法为 min⁡(qa,qb)\min(q_a,q_b),乘法为 qa+qbq_a+q_b,除法为 qa−qbq_a-q_b。精确的商以最接近首选指数的成员返回;不精确的商有 pp 位数字。零和为 +0+0,除非在 Floor 下(此时只要有一个操作数为负即为 −0-0)或两个操作数均为 −0-0。

特殊情形:∞−∞\infty-\infty、0×∞0\times\infty 与 ∞/∞\infty/\infty 产生带 invalid_operation 的 NaN;0/00/0 产生带 invalid_operation 与 division_undefined 的 NaN;对有限非零的 xx,x/0x/0 产生带 division_by_zero 的带符号无穷;有限值/∞/\infty 产生指数为 EtinyE_{\text{tiny}} 的带符号零,并引发 clamped。

///|
test "decimal context arithmetic keeps preferred exponents" {
  let ctx = @decimal.DecimalContext::decimal64()
  let d = fn(s : String) { @decimal.Decimal::from_string(s).unwrap() }
  inspect(d("1.20").add_ctx(d("3.40"), ctx).0, content="4.60")
  inspect(d("1.25").mul_ctx(d("2.50"), ctx).0, content="3.1250")
  inspect(d("2.400").div_ctx(d("1.2"), ctx).0, content="2.00")
  let (q, flags) = d("2").div_ctx(d("3"), ctx)
  inspect(q, content="0.6666666666666667")
  inspect(flags.inexact, content="true")
}

Decimal::fma_ctx

fma_ctx 以单次舍入计算 x⋅y+zx \cdot y + z。

pub fn Decimal::fma_ctx(Self, Self, Self, DecimalContext) -> (Self, DecimalFlags)

乘积被精确地构造并精确地加到 z 上;只对和进行舍入。即使 z 是静默 NaN,0×∞0\times\infty 也是无效的。符号相反的 ∞⋅y+(−∞)\infty \cdot y + (-\infty) 是无效的。在非扩展上下文中,该运算返回带 invalid_operation 的 NaN。

Decimal::sqrt_ctx

sqrt_ctx 返回正确舍入的平方根。

pub fn Decimal::sqrt_ctx(Self, DecimalContext) -> (Self, DecimalFlags)

首选指数为 ⌊q/2⌋\lfloor q/2 \rfloor。精确的根以最接近它的成员返回(sqrt(0.0400) 为 0.20);不精确的根有 pp 位数字,并引发 inexact 和 rounded。−0=−0\sqrt{-0} = -0;负的非零操作数或 −∞-\infty 产生带 invalid_operation 的 NaN;+∞=+∞\sqrt{+\infty}=+\infty。

Decimal::plus_ctx, minus_ctx, abs_ctx, apply_ctx

这些函数将单个操作数舍入到上下文。

pub fn Decimal::plus_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::minus_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::abs_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::apply_ctx(Self, DecimalContext) -> (Self, DecimalFlags)

apply_ctx 将值舍入到上下文(精度、指数范围、钳制),并将 NaN 静默化,保留零的符号。plus_ctx 即 0+x0 + x:与 apply_ctx 类似,但零变为 +0+0。minus_ctx 即 0−x0 - x,abs_ctx 即舍入到上下文的 ∣x∣|x|;信号 NaN 会引发 invalid_operation。

Decimal::divide_integer, remainder, remainder_near, remainder_ctx

这些函数计算整数商和余数。

pub fn Decimal::divide_integer(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::remainder(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::remainder_near(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::remainder_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)

divide_integer(x, y) 为 trunc⁡(x/y)\operatorname{trunc}(x/y),指数为 0。当整数商需要多于 pp 位数字时,结果为带 division_impossible 和 invalid_operation 的 NaN。remainder(x, y) 为 x−y⋅trunc⁡(x/y)x - y\cdot\operatorname{trunc}(x/y),符号与 xx 相同(General Decimal Arithmetic 的 remainder)。remainder_near(x, y) 为 x−y⋅nx - y\cdot n,其中 nn 是将 x/yx/y 就近舍入(偶数优先)得到的整数(IEEE 754 的 remainder);remainder_ctx 是同一运算。余数在可容纳时是精确的,首选指数为 min⁡(qx,qy)\min(q_x, q_y);余数为零时其符号与 xx 相同。xrem⁡0x \operatorname{rem} 0 与 ∞rem⁡y\infty \operatorname{rem} y 是无效的(0rem⁡00 \operatorname{rem} 0 还会引发 division_undefined);xrem⁡∞=xx \operatorname{rem} \infty = x。

///|
test "decimal remainders" {
  let ctx = @decimal.DecimalContext::decimal64()
  let d = fn(s : String) { @decimal.Decimal::from_string(s).unwrap() }
  inspect(d("10").divide_integer(d("3"), ctx).0, content="3")
  inspect(d("10").remainder(d("3"), ctx).0, content="1")
  inspect(d("10").remainder_near(d("6"), ctx).0, content="-2")
  inspect(d("-7.5").remainder(d("2"), ctx).0, content="-1.5")
}

量子与指数运算

Decimal::quantize

quantize 将值舍入到另一个值的指数。

pub fn Decimal::quantize(Self, Self, DecimalContext) -> (Self, DecimalFlags)

x.quantize(y, ctx) 返回指数为 qyq_y 的 x 的值,丢弃数字时以上下文的模式舍入(引发 rounded,若丢弃的数字非零还会引发 inexact)。当目标指数超出 [Etiny,emax⁡][E_{\text{tiny}}, e_{\max}]、结果系数需要多于 pp 位数字、其调整后指数超过 emax⁡e_{\max},或恰有一个操作数为无穷时,结果为带 invalid_operation 的 NaN。两个无穷产生 x 的无穷。量子从不悄然改变:若结果无法具有指数 qyq_y,运算即失败。

///|
test "decimal quantize to cents" {
  let ctx = @decimal.DecimalContext::decimal64()
  let d = fn(s : String) { @decimal.Decimal::from_string(s).unwrap() }
  let (cents, flags) = d("12.3456").quantize(d("0.01"), ctx)
  inspect(cents, content="12.35")
  inspect(flags.inexact, content="true")
  let small = @decimal.DecimalContext::new(precision=3, e_min=-99, e_max=99)
  let (bad, bad_flags) = d("999.9").quantize(d("0.1"), small)
  inspect(bad.is_nan(), content="true")
  inspect(bad_flags.invalid_operation, content="true")
}

Decimal::rescale

rescale 将指数设为一个整数操作数。

pub fn Decimal::rescale(Self, Self, DecimalContext) -> (Self, DecimalFlags)

x.rescale(n, ctx) 即目标指数为 nn 的 quantize,其中 nn 必须是有限整数;任何其他第二操作数都产生带 invalid_operation 的 NaN。

Decimal::same_quantum

same_quantum 检测两个值是否具有相同的指数。

pub fn Decimal::same_quantum(Self, Self) -> Bool

两个有限值在指数相等时具有相同的量子;两个无穷、两个 NaN 总是具有相同的量子;其他任何组合都不具有。它从不引发标志。

Decimal::reduce_ctx, normalize_ctx

这些函数将值舍入到上下文并去除尾随零。

pub fn Decimal::reduce_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::normalize_ctx(Self, DecimalContext) -> (Self, DecimalFlags)

reduce_ctx 先应用上下文,然后在指数不超过 emax⁡e_{\max}(设置 clamp 时不超过 emax⁡−p+1e_{\max}-p+1)的前提下去除尾随零。零变为指数为 0 的零(在扩展上下文中保留其符号)。normalize_ctx 是同一运算在 General Decimal Arithmetic 中的旧名称。

Decimal::to_integral_exact, to_integral_value

这些函数舍入到整数。

pub fn Decimal::to_integral_exact(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::to_integral_value(Self, DecimalContext) -> (Self, DecimalFlags)

指数为负的有限值以上下文的舍入模式量化到指数 0;指数 ≥0\ge 0 的值仅舍入到上下文。to_integral_exact 报告 rounded/inexact;to_integral_value 返回相同的值,但清除这两个标志。无穷原样返回;NaN 被静默化。

Decimal::scaleb_ctx, logb_ctx

这些函数按 10 的幂进行缩放,并提取调整后指数。

pub fn Decimal::scaleb_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::logb_ctx(Self, DecimalContext) -> (Self, DecimalFlags)

x.scaleb_ctx(n, ctx) 通过将 nn 加到指数上返回 x⋅10nx \cdot 10^{n};nn 必须是指数为 0 且满足 ∣n∣≤2(emax⁡+p)|n| \le 2(e_{\max}+p) 的有限整数,否则结果为带 invalid_operation 的 NaN。结果保留 x 的系数(不舍入到 pp 位),应用次正规与钳制规则,并在所有舍入模式下上溢为带 overflow、inexact 和 rounded 的带符号无穷。logb_ctx(x) 以整数 Decimal 的形式返回调整后指数 ⌊log⁡10∣x∣⌋\lfloor\log_{10}|x|\rfloor;logb⁡(±0)=−∞\operatorname{logb}(\pm 0) = -\infty 并引发 division_by_zero,logb⁡(±∞)=+∞\operatorname{logb}(\pm\infty) = +\infty。

相邻值

Decimal::next_plus, next_minus, next_toward

这些函数返回相邻的可表示值。

pub fn Decimal::next_plus(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::next_minus(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::next_toward(Self, Self, DecimalContext) -> (Self, DecimalFlags)

next_plus 是上下文中大于 x 的最小可表示值,next_minus 是比它小的最大可表示值,范围包括低至 10Etiny10^{E_{\text{tiny}}} 的次正规数以及最大有限值 (10p−1) 10emax⁡−p+1(10^{p}-1)\,10^{e_{\max}-p+1};next_plus(-∞) 是最小(最负)的有限值。对有限结果,它们不引发任何标志。next_toward(x, y) 将 x 朝 y 移动一步;当 x=yx = y 时返回 x,对零则取 y 的符号。next_toward 的一步若落到无穷,则引发 overflow、inexact 和 rounded;若落到次正规数或零,则引发 underflow、subnormal、inexact 和 rounded。

///|
test "decimal neighbours of one" {
  let ctx = @decimal.DecimalContext::decimal64()
  let one = @decimal.Decimal::one()
  inspect(one.next_plus(ctx).0, content="1.000000000000001")
  inspect(one.next_minus(ctx).0, content="0.9999999999999999")
}

比较与排序

Decimal::compare, equal, not_equal, op_lt, op_le, op_gt, op_ge

compare 是 Compare 及比较运算符所使用的数值三路比较。

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

compare 按数值返回 −1-1、0 或 1,其中 −0=+0-0 = +0,同值类的所有成员相等。NaN 没有数值顺序,为使 Compare 保持全预序(排序永不中止),每个 NaN 与其他任何 NaN 比较相等,且大于所有非 NaN。equal(==)与 compare 一致:NaN == NaN 为 true。这不是 IEEE 相等;当 NaN 必须无序时,请使用 compare_checked、compare_ctx 或 NaN 谓词。op_lt 等是 Compare 被提升的运算符方法。

///|
test "decimal numeric order is a total preorder" {
  let d = fn(s : String) { @decimal.Decimal::from_string(s).unwrap() }
  inspect(d("1.0") == d("1.00"), content="true")
  inspect(d("-0").compare(d("0")), content="0")
  inspect(@decimal.Decimal::nan().compare(d("1E+999")), content="1")
  let sorted = [d("2"), @decimal.Decimal::nan(), d("-1")]
  sorted.sort()
  inspect(sorted.map(fn(x) { x.to_string() }).join(" "), content="-1 2 nan")
}

Decimal::compare_checked

compare_checked 是将 NaN 视为错误的 IEEE 数值比较。

pub fn Decimal::compare_checked(Self, Self) -> Result[Int, @arithmetic.ArithmeticError]

当两个操作数都不是 NaN 时,它返回 Ok(compare(x, y)),否则返回 Err(unordered_comparison)。它是 CompareChecked 的实现。

Decimal::compare_ctx, compare_signal_ctx

这些函数是结果为十进制值的 General Decimal Arithmetic 比较。

pub fn Decimal::compare_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::compare_signal_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)

它们返回 Decimal 值 −1-1、0 或 1;当某个操作数为 NaN 时返回静默 NaN。compare_ctx 仅对信号 NaN 引发 invalid_operation;compare_signal_ctx 对所有 NaN 都引发(IEEE signaling 比较)。

Decimal::compare_total, compare_total_magnitude, compare_total_ctx, compare_total_magnitude_ctx

这些函数以三路比较的形式实现 IEEE 754 的 totalOrder 谓词。

pub fn Decimal::compare_total(Self, Self) -> Int
pub fn Decimal::compare_total_magnitude(Self, Self) -> Int
pub fn Decimal::compare_total_ctx(Self, Self, DecimalContext) -> (Int, DecimalFlags)
pub fn Decimal::compare_total_magnitude_ctx(Self, Self, DecimalContext) -> (Int, DecimalFlags)

compare_total 对所有表示进行排序:

−NaN<−sNaN<−∞<negative finite<−0<+0<positive finite<+∞<+sNaN<+NaN.-\text{NaN} < -\text{sNaN} < -\infty < \text{negative finite} < -0 < +0 < \text{positive finite} < +\infty < +\text{sNaN} < +\text{NaN}.

相等的有限值按指数排序:对正值,较小指数在前(1.00<1.01.00 < 1.0),对负值则较大指数在前。符号与种类相同的 NaN 按载荷排序(负 NaN 则逆序)。仅当表示完全相同时才返回 0。compare_total_magnitude 比较绝对值。_ctx 形式先为上下文准备操作数(仅在子集模式下有影响),并返回该步骤的标志。

Decimal::min, max, clamp, clamp_checked

这些函数在无上下文的情况下按数值顺序进行选择。

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

当恰有一个操作数是静默 NaN 时,min 和 max 返回另一个操作数;当两者都是 NaN 或任一为信号 NaN 时,返回静默 NaN;相等时返回接收者。clamp 在低于范围时返回 min,高于范围时返回 max,否则返回该值(包括 NaN);当某个边界为 NaN 或 min > max 时中止。clamp_checked 在这些情形下返回 Err(domain_error)。

Decimal::min_ctx, max_ctx, min_mag_ctx, max_mag_ctx

这些函数是 General Decimal Arithmetic 的 min、max、min-magnitude 和 max-magnitude 运算。

pub fn Decimal::min_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::max_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::min_mag_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::max_mag_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)

静默 NaN 输给数值;两个 NaN 时返回静默化后的第一个;信号 NaN 产生带 invalid_operation 的静默 NaN。数值相等的操作数由 compare_total 区分(因此 min_ctx(1.0, 1.00) 为 1.00,min_ctx(-0, 0) 为 -0)。所选的值被舍入到上下文。

IEEE 最小值与最大值

这十二个函数是 IEEE 754-2019 §9.6 中的最小值与最大值运算。

pub fn Decimal::minimum_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::maximum_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::minimum_number_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::maximum_number_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::minimum_magnitude_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::maximum_magnitude_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::minimum_number_magnitude_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::maximum_number_magnitude_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::minimum_mag_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::maximum_mag_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::minimum_number_mag_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::maximum_number_mag_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)

minimum_ctx 和 maximum_ctx 传播 NaN:任何 NaN 操作数都产生静默 NaN。_number_ 变体在恰有一个操作数为 NaN 时返回数值。在这两种情形下,信号 NaN 都会引发 invalid_operation。按大小比较的变体比较 ∣x∣|x| 与 ∣y∣|y|,大小相等时退回到带符号的顺序。相等时由 compare_total 决定,因此 −0<+0-0 < +0。_mag_ 写法是 _magnitude_ 写法的别名。所选的值被舍入到上下文。

逐位运算

Decimal::logical_and, logical_or, logical_xor, logical_invert

这些函数对逻辑操作数逐位应用布尔运算。

pub fn Decimal::logical_and(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::logical_or(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::logical_xor(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::logical_invert(Self, DecimalContext) -> (Self, DecimalFlags)

逻辑操作数是指数为 0、系数各位均为 0 或 1 的有限非负值,例如 1101。运算作用于低 pp 位并返回一个逻辑操作数;任何其他操作数都产生带 invalid_operation 的 NaN。

Decimal::shift_ctx, rotate_ctx

这些函数对系数数字进行移位或循环移位。

pub fn Decimal::shift_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::rotate_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)

系数被视为 pp 位数字。正的计数 nn 将数字向最高有效端移动,负的计数则向最低有效端移动;shift_ctx 用零填充并丢弃移出窗口的数字,rotate_ctx 则将它们循环移回。指数与符号保持不变。计数必须是指数为 0 且 ∣n∣≤p|n| \le p 的整数;否则结果为带 invalid_operation 的 NaN。无穷原样返回。

初等函数

每个初等函数都有两种形式。f_ctx(x, ctx) 返回 (result, flags)。try_f_ctx(x, ctx) 在 Ok 中返回同样的二元组;当结果无法认证时返回 Err,其中的 ArithmeticError 的 certification_failure_detail() 给出运算名称、目标精度以及已耗尽的细化预算。认证失败时,f_ctx 返回带 invalid_operation 的 NaN。

在每种 DecimalRoundingMode 下,有限结果都是正确舍入的:实现会在 ball_float 中计算 f(x)f(x) 的一个有保证的包络,仅当两个端点以相同标志舍入到同一个 Decimal 时才接受它(参见设计)。精确情形(例如 log⁡101000=3\log_{10} 1000 = 3、e0=1e^0 = 1、sin⁡0=0\sin 0 = 0、cospi⁡(1)=−1\operatorname{cospi}(1) = -1、整数次幂)会被检测出来并精确返回,不带 inexact。

当 p>999 999p > 999\,999、emax⁡>999 999e_{\max} > 999\,999 或 emin⁡<−999 999e_{\min} < -999\,999,或者某个有限操作数超过 999,999 位数字、或其调整后指数超出约 ±106\pm 10^6 时,它们都返回带 invalid_context 的 NaN。

Decimal::exp_ctx、ln_ctx、log10_ctx 及其 try_ 形式

这些函数是 General Decimal Arithmetic 的指数函数与对数函数。

pub fn Decimal::exp_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::ln_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::log10_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::try_exp_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_ln_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_log10_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]

e±0=1e^{\pm 0} = 1,e+∞=+∞e^{+\infty}=+\infty,e−∞=+0e^{-\infty} = +0。±0\pm 0 的 ln⁡\ln 和 log⁡10\log_{10} 为 −∞-\infty(在扩展上下文中不引发标志),+∞+\infty 的为 +∞+\infty,负值或 −∞-\infty 的为带 invalid_operation 的 NaN;ln⁡1=0\ln 1 = 0,10 的幂的 log⁡10\log_{10} 为精确的整数指数。对于大到或小到 exe^x 必然上溢或下溢的参数,无需求值即可判定。

Decimal::power_ctx、pown_ctx、rootn_ctx、hypot_ctx 及其 try_ 形式

这些函数计算幂、方根和欧几里得范数。

pub fn Decimal::power_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::pown_ctx(Self, Int, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::rootn_ctx(Self, Int, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::hypot_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::try_power_ctx(Self, Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_pown_ctx(Self, Int, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_rootn_ctx(Self, Int, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_hypot_ctx(Self, Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]

power_ctx(x, y) 即 xyx^y,并采用 General Decimal Arithmetic 的特殊情形:整数指数通过带额外工作位的精确重复乘法计算,并只舍入一次;x0.5x^{0.5} 即 sqrt_ctx;正底数配非整数指数会经过认证;负底数配非整数指数是无效的;在扩展上下文中 000^0 是无效的;0−n0^{-n} 为 ±∞\pm\infty。pown_ctx(x, n) 即把整数 n 转换为上下文精度的 Decimal 后的 power_ctx。rootn_ctx(x, n) 对整数 n≠0n \ne 0 为 x1/nx^{1/n};负值的偶次方根以及 n=0n=0 是无效的,rootn⁡(±0,n<0)\operatorname{rootn}(\pm 0, n<0) 为带 division_by_zero 的无穷。hypot_ctx(x, y) 即 x2+y2\sqrt{x^2+y^2};只要任一操作数为无穷,结果就是 +∞+\infty,即使另一个是静默 NaN。

扩展初等函数

这些 IEEE 754-2019 §9.2 函数具有相同的 f_ctx/try_f_ctx 形式。

pub fn Decimal::exp2_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::exp10_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::expm1_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::log2_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::log1p_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::sin_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::cos_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::tan_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::sinpi_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::cospi_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::tanpi_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::asin_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::acos_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::atan_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::atan2_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::sinh_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::cosh_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::tanh_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::asinh_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::acosh_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::atanh_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::try_exp2_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_exp10_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_expm1_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_log2_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_log1p_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_sin_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_cos_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_tan_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_sinpi_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_cospi_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_tanpi_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_asin_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_acos_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_atan_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_atan2_ctx(Self, Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_sinh_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_cosh_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_tanh_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_asinh_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_acosh_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_atanh_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]

定义域与特殊值:

函数无效(invalid_operation)极点(division_by_zero)精确情形
exp2, exp10无无整数参数(通过 power_ctx),±0↦1\pm 0 \mapsto 1
expm1无无±0↦±0\pm0 \mapsto \pm0, −∞↦−1-\infty\mapsto -1
log2x<0x<0, −∞-\infty±0↦−∞\pm 0 \mapsto -\infty1↦01 \mapsto 0
log1px<−1x<-1, ±∞\pm\infty−1↦−∞-1 \mapsto -\infty±0↦±0\pm0 \mapsto \pm0
sin, cos, tan±∞\pm\infty无sin⁡(±0)=±0\sin(\pm 0)=\pm 0, cos⁡0=1\cos 0 = 1
sinpi, cospi, tanpi±∞\pm\inftytanpi 在奇数的一半处整数与半整数
asin, acos∣x∣>1\lvert x\rvert > 1, ±∞\pm\infty无asin⁡(±0)=±0\operatorname{asin}(\pm0)=\pm0
atan无无±0\pm 0;±∞↦±π/2\pm\infty \mapsto \pm\pi/2(经过认证)
atan2(y, x)无无atan2⁡(±0,+0)=±0\operatorname{atan2}(\pm 0, +0) = \pm 0
sinh, tanh, asinh无无±0↦±0\pm0\mapsto\pm0; tanh⁡(±∞)=±1\tanh(\pm\infty)=\pm 1
cosh无无cosh⁡0=1\cosh 0 = 1, cosh⁡(±∞)=+∞\cosh(\pm\infty)=+\infty
acoshx<1x < 1, −∞-\infty无1↦01 \mapsto 0
atanh∣x∣>1\lvert x\rvert>1, ±∞\pm\infty±1↦±∞\pm1 \mapsto \pm\infty±0↦±0\pm0 \mapsto \pm0
///|
test "decimal certified elementary functions" {
  let ctx = @decimal.DecimalContext::decimal64()
  let d = fn(s : String) { @decimal.Decimal::from_string(s).unwrap() }
  inspect(d("1").exp_ctx(ctx).0, content="2.718281828459045")
  inspect(d("1000").log10_ctx(ctx).0, content="3")
  inspect(d("0.5").sinpi_ctx(ctx).0, content="1")
  let down = ctx.with_rounding(@def.RoundingMode::TowardZero)
  inspect(d("2").ln_ctx(down).0, content="0.6931471805599453")
  match d("2").try_ln_ctx(@decimal.DecimalContext::new()) {
    Ok((value, flags)) => {
      inspect(value.is_nan(), content="true")
      inspect(flags.invalid_context, content="true")
    }
    Err(_) => fail("not a certification failure")
  }
}

交换格式

DecimalInterchangeFormat

DecimalInterchangeFormat 指定一种 IEEE 754 十进制交换格式。

pub(all) enum DecimalInterchangeFormat {
  Decimal32
  Decimal64
  Decimal128
}
pub fn DecimalInterchangeFormat::context(Self) -> DecimalContext
pub fn DecimalInterchangeFormat::equal(Self, Self) -> Bool
pub fn DecimalInterchangeFormat::not_equal(Self, Self) -> Bool

context 返回 DecimalContext::decimal32()、decimal64() 或 decimal128()。

DecimalInterchangeEncoding

DecimalInterchangeEncoding 选择系数在比特中的存储方式。

pub(all) enum DecimalInterchangeEncoding {
  DPD
  BID
}
pub fn DecimalInterchangeEncoding::equal(Self, Self) -> Bool
pub fn DecimalInterchangeEncoding::not_equal(Self, Self) -> Bool

DPD 每个 10 位 declet 存储三个十进制数字(densely packed decimal,密集压缩十进制);BID 将系数存储为二进制整数。没有编码参数的函数使用 DPD。

Decimal::to_interchange_hex, to_interchange_hex_with_encoding

这些函数将值编码为以十六进制书写的交换比特。

pub fn Decimal::to_interchange_hex(Self, DecimalInterchangeFormat) -> (String, DecimalFlags)
pub fn Decimal::to_interchange_hex_with_encoding(Self, DecimalInterchangeFormat, DecimalInterchangeEncoding) -> (String, DecimalFlags)

有限值先在格式上下文下用 apply_ctx 舍入(返回其标志),再连同其指数一起编码,因此在可容纳时会保留同值类成员。文本为 # 后跟 8、16 或 32 个大写十六进制数字。无穷以全零的尾随字段编码。NaN 保留其符号和种类;DPD 保留载荷的低 p−1p-1 位,而 BID 保留以 pvalue−1p_{\text{value}}-1 位书写的载荷的前 p−1p-1 位,因此只有当值的精度等于格式精度时,载荷才能可移植地用于 BID。

Decimal::from_interchange_hex, from_interchange_hex_with_encoding

这些函数解码交换十六进制文本。

pub fn Decimal::from_interchange_hex(String, DecimalInterchangeFormat) -> Self?
pub fn Decimal::from_interchange_hex_with_encoding(String, DecimalInterchangeFormat, DecimalInterchangeEncoding) -> Self?

文本两侧可以有 ASCII 空白,并可带前导 #;它必须恰好具有该格式规定数量的十六进制数字(大小写均可),否则结果为 None。解码是精确的,并保留指数、零的符号、NaN 种类和载荷。非规范编码被解码为 IEEE 754 为其指定的值:非规范的 DPD declet 解码为其数字,满足 ≥10p\ge 10^{p} 的 BID 系数解码为零,超出范围的 BID NaN 载荷解码为 0;无穷与 NaN 中未使用的指数位被忽略。结果具有该格式的精度。

///|
test "decimal64 interchange in both encodings" {
  let x = @decimal.Decimal::from_string("1.25").unwrap()
  let fmt = @decimal.DecimalInterchangeFormat::Decimal64
  let (dpd, _) = x.to_interchange_hex(fmt)
  let (bid, _) = x.to_interchange_hex_with_encoding(
    fmt,
    @decimal.DecimalInterchangeEncoding::BID,
  )
  inspect(dpd, content="#22300000000000A5")
  inspect(bid, content="#318000000000007D")
  let back = @decimal.Decimal::from_interchange_hex(dpd, fmt).unwrap()
  inspect(back, content="1.25")
}

DecimalInterchange

DecimalInterchange 保存一个交换值的原始比特及其格式和编码。

pub struct DecimalInterchange {
  // private fields
}
pub fn DecimalInterchange::format(Self) -> DecimalInterchangeFormat
pub fn DecimalInterchange::encoding(Self) -> DecimalInterchangeEncoding
pub fn DecimalInterchange::to_hex(Self) -> String

当需要检查或精确保留比特时(包括 Decimal 无法表示的非规范编码),请使用它。to_hex 写出 # 以及全宽的大写十六进制数字。

DecimalInterchange::from_hex, from_hex_with_encoding, from_decimal, from_decimal_with_encoding

这些函数由文本或 Decimal 构建交换值。

pub fn DecimalInterchange::from_hex(String, DecimalInterchangeFormat) -> Self?
pub fn DecimalInterchange::from_hex_with_encoding(String, DecimalInterchangeFormat, DecimalInterchangeEncoding) -> Self?
pub fn DecimalInterchange::from_decimal(Decimal, DecimalInterchangeFormat) -> (Self, DecimalFlags)
pub fn DecimalInterchange::from_decimal_with_encoding(Decimal, DecimalInterchangeFormat, DecimalInterchangeEncoding) -> (Self, DecimalFlags)

from_hex 原样存储比特(文本规则同 from_interchange_hex)。from_decimal 的编码方式与 to_interchange_hex 相同,并返回相同的标志。不带编码参数的形式使用 DPD。

DecimalInterchange::to_decimal, to_decimal_ctx

这些函数解码所存储的比特。

pub fn DecimalInterchange::to_decimal(Self) -> Decimal
pub fn DecimalInterchange::to_decimal_ctx(Self) -> (Decimal, DecimalFlags)

解码是精确的。若解码值在该格式中为次正规数,to_decimal_ctx 还会引发 subnormal;不可能出现其他标志。

DecimalInterchange::canonical, is_canonical

这些函数将所存储的比特规范化。

pub fn DecimalInterchange::canonical(Self) -> Self
pub fn DecimalInterchange::is_canonical(Self) -> Bool

canonical 以相同的格式和编码进行解码并重新编码:每个非规范的 declet、超出范围的 BID 系数以及无穷或 NaN 中未使用的比特都被替换为其规范形式。它是幂等的。is_canonical 检测比特是否已经是规范的。

DecimalInterchange::copy, copy_abs, copy_negate, copy_sign

这些函数只改变所存储比特中的符号位。

pub fn DecimalInterchange::copy(Self) -> Self
pub fn DecimalInterchange::copy_abs(Self) -> Self
pub fn DecimalInterchange::copy_negate(Self) -> Self
pub fn DecimalInterchange::copy_sign(Self, Self) -> Self

其他所有比特(无论是否规范)都被保留。除非两个操作数具有相同的格式和编码,否则 copy_sign 会中止。

trait 实现

代数 trait

Decimal 通过普通运算符实现 Luna-Flow 代数 trait。

pub impl @luna-generic.Zero for Decimal
pub impl @luna-generic.One for Decimal
pub impl @luna-generic.AddMonoid for Decimal
pub impl @luna-generic.MulMonoid for Decimal
pub impl @luna-generic.AddGroup for Decimal
pub impl @luna-generic.Semiring for Decimal
pub impl @luna-generic.Ring for Decimal
pub impl @luna-generic.NatHomomorphism for Decimal
pub impl @luna-generic.IntegralHomomorphism for Decimal
pub impl Add for Decimal
pub impl Sub for Decimal
pub impl Mul for Decimal
pub impl Div for Decimal
pub impl Neg for Decimal
pub impl Eq for Decimal
pub impl Compare for Decimal

Zero::zero() 和 One::one() 即 Decimal::zero() 和 Decimal::one()。只要没有和被舍入(精确系数能容纳于操作数精度的和,以及所有乘积,因为 * 是精确的),环公理对 +、- 和 * 精确成立;经过舍入的和只是近似满足结合律。from_nat 和 from_integral 的说明见构造。

@def.Floating

Decimal 实现了 floating 的标量 trait。

pub impl @def.Floating for Decimal

trait 方法为 classify、sign、precision、with_precision 和 normalized,均已在上文说明;@def.is_finite(x) 及其他泛型谓词都通过它工作。

contextual trait

Decimal 实现了 Luna-Flow/arithmetic 的 contextual trait。

pub fn Decimal::add_contextual(Self, Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]
pub fn Decimal::sub_contextual(Self, Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]
pub fn Decimal::mul_contextual(Self, Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]
pub fn Decimal::div_contextual(Self, Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]
pub fn Decimal::abs_contextual(Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]
pub fn Decimal::sqrt_contextual(Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]
pub fn Decimal::exp_contextual(Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]
pub fn Decimal::zero_contextual(@arithmetic.ArithmeticContext) -> Self
pub fn Decimal::one_contextual(@arithmetic.ArithmeticContext) -> Self
pub fn Decimal::epsilon_contextual(@arithmetic.ArithmeticContext) -> Self
pub fn Decimal::min_normal_contextual(@arithmetic.ArithmeticContext) -> Self
pub fn Decimal::max_finite_contextual(@arithmetic.ArithmeticContext) -> Self
pub fn Decimal::classify_contextual(Self) -> @arithmetic.FpClass
pub impl @arithmetic.AddContextual for Decimal
pub impl @arithmetic.SubContextual for Decimal
pub impl @arithmetic.MulContextual for Decimal
pub impl @arithmetic.DivContextual for Decimal
pub impl @arithmetic.AbsContextual for Decimal
pub impl @arithmetic.SqrtContextual for Decimal
pub impl @arithmetic.ExpContextual for Decimal
pub impl @arithmetic.NumericFormatContextual for Decimal

每个 *_contextual 运算都用 DecimalContext::from_arithmetic_context 转换上下文,执行对应的 *_ctx 运算:若引发了 division_by_zero 则返回 Err(division_by_zero),若引发了其他 has_error 标志则返回 Err(domain_error),否则返回 Ok,其诊断信息 inexact、rounded、overflow、underflow、subnormal 和 clamped 复制自标志。由于转换后的上下文采用默认指数范围,未显式指定 e_min/e_max 的 exp_contextual 会以 domain_error(invalid_context)失败。

zero_contextual 和 one_contextual 具有上下文精度。epsilon_contextual 为 101−p10^{1-p}(next_plus(1) - 1)。min_normal_contextual 为 10emin⁡10^{e_{\min}}(默认 emin⁡=−999 999 999e_{\min} = -999\,999\,999)。max_finite_contextual 为 (10p−1) 10emax⁡−p+1(10^{p}-1)\,10^{e_{\max}-p+1}。classify_contextual 即 classify。

checked trait

Decimal 实现了 Luna-Flow/arithmetic 的 checked trait。

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

parse_checked(s, ctx) 即 Decimal::parse(s, precision=ctx.precision)。DivChecked::div_checked(x, y, ctx) 即转换后上下文下的 div_ctx,其 Err(division_by_zero) 与 Err(domain_error) 同 div_checked。sqrt_checked 即转换后上下文下的 sqrt_ctx,对负操作数失败。pow_nat_checked 和 pow_int_checked 即把整数指数转换为上下文精度的 Decimal 后的 power_ctx;对零底数配负指数返回 Err(division_by_zero),对无效的幂返回 Err(domain_error),且 pow_nat_checked 对大于 999,999,999 的指数返回 Err(unsupported)。CompareChecked 即 compare_checked。

Show 与 Debug

Decimal 实现了 Show 和 Debug。

pub impl Show for Decimal
pub fn Decimal::to_repr(Self) -> @debug.Repr

Show 提供 to_string 和 output。to_repr 是派生的结构化表示,供 debug_inspect 和 assert_eq 使用。

完整公共接口

此快照是该包生成的 pkg.generated.mbti。当正文与接口不一致时,以接口为准。

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

import {
  "Luna-Flow/arithmetic",
  "Luna-Flow/floating/bin_float",
  "Luna-Flow/floating/def",
  "Luna-Flow/luna-generic",
  "moonbitlang/core/bigint",
  "moonbitlang/core/debug",
}

// Values

// Errors

// Types and methods
pub struct Decimal {
  // private fields
} derive(@debug.Debug)
pub fn Decimal::abs(Self) -> Self
pub fn Decimal::abs_contextual(Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]
pub fn Decimal::abs_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::acos_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::acosh_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::add(Self, Self) -> Self
pub fn Decimal::add_contextual(Self, Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]
pub fn Decimal::add_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::apply_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::asin_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::asinh_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::atan2_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::atan_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::atanh_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::clamp(Self, min~ : Self, max~ : Self) -> Self
pub fn Decimal::clamp_checked(Self, min~ : Self, max~ : Self) -> Result[Self, @arithmetic.ArithmeticError]
pub fn Decimal::class_name(Self, DecimalContext) -> String
pub fn Decimal::classify(Self) -> @arithmetic.FpClass
pub fn Decimal::classify_contextual(Self) -> @arithmetic.FpClass
pub fn Decimal::coefficient(Self) -> @bigint.BigInt
pub fn Decimal::compare(Self, Self) -> Int
pub fn Decimal::compare_checked(Self, Self) -> Result[Int, @arithmetic.ArithmeticError]
pub fn Decimal::compare_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::compare_signal_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::compare_total(Self, Self) -> Int
pub fn Decimal::compare_total_ctx(Self, Self, DecimalContext) -> (Int, DecimalFlags)
pub fn Decimal::compare_total_magnitude(Self, Self) -> Int
pub fn Decimal::compare_total_magnitude_ctx(Self, Self, DecimalContext) -> (Int, DecimalFlags)
pub fn Decimal::copy(Self) -> Self
pub fn Decimal::copy_abs(Self) -> Self
pub fn Decimal::copy_negate(Self) -> Self
pub fn Decimal::copy_sign(Self, Self) -> Self
pub fn Decimal::cos_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::cosh_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::cospi_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::div(Self, Self) -> Self
pub fn Decimal::div_checked(Self, Self) -> Result[Self, @arithmetic.ArithmeticError]
pub fn Decimal::div_contextual(Self, Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]
pub fn Decimal::div_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::divide_integer(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::epsilon_contextual(@arithmetic.ArithmeticContext) -> Self
pub fn Decimal::equal(Self, Self) -> Bool
pub fn Decimal::exp10_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::exp2_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::exp_contextual(Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]
pub fn Decimal::exp_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::expm1_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::exponent10(Self) -> Int
pub fn Decimal::fma_ctx(Self, Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::from_bigint(@bigint.BigInt, precision? : Int) -> Self
pub fn Decimal::from_bin_float(@bin_float.BinFloat, precision? : Int) -> Self
pub fn Decimal::from_double(Double, precision? : Int) -> Self
pub fn Decimal::from_float(Float, precision? : Int) -> Self
pub fn Decimal::from_int(Int, precision? : Int) -> Self
pub fn[S : @luna-generic.Integral] Decimal::from_integral(S) -> Self
pub fn Decimal::from_interchange_hex(String, DecimalInterchangeFormat) -> Self?
pub fn Decimal::from_interchange_hex_with_encoding(String, DecimalInterchangeFormat, DecimalInterchangeEncoding) -> Self?
pub fn[S : @luna-generic.Nat] Decimal::from_nat(S) -> Self
pub fn Decimal::from_string(String, precision? : Int) -> Self?
pub fn Decimal::from_string_ctx(String, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::get_payload(Self) -> @bigint.BigInt
pub fn Decimal::hypot_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::inf(@def.Sign, precision? : Int) -> Self
pub fn Decimal::is_canonical(Self) -> Bool
pub fn Decimal::is_finite(Self) -> Bool
pub fn Decimal::is_infinite(Self) -> Bool
pub fn Decimal::is_nan(Self) -> Bool
pub fn Decimal::is_negative(Self) -> Bool
pub fn Decimal::is_negative_zero(Self) -> Bool
pub fn Decimal::is_normal(Self, DecimalContext) -> Bool
pub fn Decimal::is_qnan(Self) -> Bool
pub fn Decimal::is_quiet_nan(Self) -> Bool
pub fn Decimal::is_signaling_nan(Self) -> Bool
pub fn Decimal::is_signed(Self) -> Bool
pub fn Decimal::is_snan(Self) -> Bool
pub fn Decimal::is_subnormal(Self, DecimalContext) -> Bool
pub fn Decimal::is_zero(Self) -> Bool
pub fn Decimal::ln_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::log10_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::log1p_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::log2_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::logb_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::logical_and(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::logical_invert(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::logical_or(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::logical_xor(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::magnitude(Self) -> @bigint.BigInt
pub fn Decimal::make(@bigint.BigInt, Int, Int, mode? : @arithmetic.RoundingMode) -> Self
pub fn Decimal::max(Self, Self) -> Self
pub fn Decimal::max_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::max_finite_contextual(@arithmetic.ArithmeticContext) -> Self
pub fn Decimal::max_mag_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::maximum_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::maximum_mag_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::maximum_magnitude_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::maximum_number_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::maximum_number_mag_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::maximum_number_magnitude_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::min(Self, Self) -> Self
pub fn Decimal::min_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::min_mag_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::min_normal_contextual(@arithmetic.ArithmeticContext) -> Self
pub fn Decimal::minimum_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::minimum_mag_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::minimum_magnitude_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::minimum_number_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::minimum_number_mag_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::minimum_number_magnitude_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::minus_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::mul(Self, Self) -> Self
pub fn Decimal::mul_contextual(Self, Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]
pub fn Decimal::mul_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::nan(precision? : Int) -> Self
pub fn Decimal::nan_payload(Self) -> @bigint.BigInt
pub fn Decimal::neg(Self) -> Self
pub fn Decimal::negative_zero(precision? : Int) -> Self
pub fn Decimal::next_minus(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::next_plus(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::next_toward(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::normalize_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::normalized(Self) -> Self
pub fn Decimal::not_equal(Self, Self) -> Bool
pub fn Decimal::one(precision? : Int) -> Self
pub fn Decimal::one_contextual(@arithmetic.ArithmeticContext) -> Self
pub fn Decimal::op_ge(Self, Self) -> Bool
pub fn Decimal::op_gt(Self, Self) -> Bool
pub fn Decimal::op_le(Self, Self) -> Bool
pub fn Decimal::op_lt(Self, Self) -> Bool
pub fn Decimal::output(Self, &Logger) -> Unit
pub fn Decimal::parse(String, precision? : Int) -> Result[Self, @arithmetic.ArithmeticError]
pub fn Decimal::parse_checked(String, @arithmetic.ArithmeticContext) -> Result[Self, @arithmetic.ArithmeticError]
pub fn Decimal::plus_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::pow_int_checked(Self, Int, @arithmetic.ArithmeticContext) -> Result[Self, @arithmetic.ArithmeticError]
pub fn Decimal::pow_nat_checked(Self, UInt, @arithmetic.ArithmeticContext) -> Result[Self, @arithmetic.ArithmeticError]
pub fn Decimal::power_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::pown_ctx(Self, Int, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::precision(Self) -> Int
pub fn Decimal::quantize(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::quantum(Self) -> Int
pub fn Decimal::quiet_nan(payload? : @bigint.BigInt, negative? : Bool, precision? : Int) -> Self
pub fn Decimal::reduce_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::remainder(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::remainder_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::remainder_near(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::rescale(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::rootn_ctx(Self, Int, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::rotate_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::same_quantum(Self, Self) -> Bool
pub fn Decimal::scaleb_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::set_payload(Self, @bigint.BigInt) -> Self
pub fn Decimal::set_payload_signaling(Self, @bigint.BigInt) -> Self
pub fn Decimal::shift_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::sign(Self) -> @def.Sign
pub fn Decimal::signaling_nan(payload? : @bigint.BigInt, negative? : Bool, precision? : Int) -> Self
pub fn Decimal::sin_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::sinh_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::sinpi_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::sqrt(Self) -> Result[Self, @arithmetic.ArithmeticError]
pub fn Decimal::sqrt_checked(Self, @arithmetic.ArithmeticContext) -> Result[Self, @arithmetic.ArithmeticError]
pub fn Decimal::sqrt_contextual(Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]
pub fn Decimal::sqrt_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::sub(Self, Self) -> Self
pub fn Decimal::sub_contextual(Self, Self, @arithmetic.ArithmeticContext) -> Result[@arithmetic.ArithmeticOutcome[Self], @arithmetic.ArithmeticError]
pub fn Decimal::sub_ctx(Self, Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::tan_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::tanh_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::tanpi_ctx(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::to_bin_float(Self, precision? : Int, mode? : @arithmetic.RoundingMode) -> @bin_float.BinFloat
pub fn Decimal::to_eng_string(String, DecimalContext) -> (String, DecimalFlags)
pub fn Decimal::to_integral_exact(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::to_integral_value(Self, DecimalContext) -> (Self, DecimalFlags)
pub fn Decimal::to_interchange_hex(Self, DecimalInterchangeFormat) -> (String, DecimalFlags)
pub fn Decimal::to_interchange_hex_with_encoding(Self, DecimalInterchangeFormat, DecimalInterchangeEncoding) -> (String, DecimalFlags)
pub fn Decimal::to_repr(Self) -> @debug.Repr
pub fn Decimal::to_sci_string(String, DecimalContext) -> (String, DecimalFlags)
pub fn Decimal::to_string(Self) -> String
pub fn Decimal::trim(Self) -> Self
pub fn Decimal::try_acos_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_acosh_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_asin_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_asinh_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_atan2_ctx(Self, Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_atan_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_atanh_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_cos_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_cosh_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_cospi_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_exp10_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_exp2_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_exp_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_expm1_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_hypot_ctx(Self, Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_ln_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_log10_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_log1p_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_log2_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_power_ctx(Self, Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_pown_ctx(Self, Int, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_rootn_ctx(Self, Int, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_sin_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_sinh_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_sinpi_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_tan_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_tanh_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::try_tanpi_ctx(Self, DecimalContext) -> Result[(Self, DecimalFlags), @arithmetic.ArithmeticError]
pub fn Decimal::with_precision(Self, Int, @arithmetic.RoundingMode) -> Self
pub fn Decimal::zero(precision? : Int) -> Self
pub fn Decimal::zero_contextual(@arithmetic.ArithmeticContext) -> Self
pub impl @arithmetic.AbsContextual for Decimal
pub impl @arithmetic.AddContextual for Decimal
pub impl @arithmetic.CompareChecked for Decimal
pub impl @arithmetic.DivChecked for Decimal
pub impl @arithmetic.DivContextual for Decimal
pub impl @arithmetic.ExpContextual for Decimal
pub impl @arithmetic.MulContextual for Decimal
pub impl @arithmetic.NumericFormatContextual for Decimal
pub impl @arithmetic.ParseChecked for Decimal
pub impl @arithmetic.PowIntChecked for Decimal
pub impl @arithmetic.PowNatChecked for Decimal
pub impl @arithmetic.SqrtChecked for Decimal
pub impl @arithmetic.SqrtContextual for Decimal
pub impl @arithmetic.SubContextual for Decimal
pub impl @def.Floating for Decimal
pub impl @luna-generic.AddGroup for Decimal
pub impl @luna-generic.AddMonoid for Decimal
pub impl @luna-generic.IntegralHomomorphism for Decimal
pub impl @luna-generic.MulMonoid for Decimal
pub impl @luna-generic.NatHomomorphism for Decimal
pub impl @luna-generic.One for Decimal
pub impl @luna-generic.Ring for Decimal
pub impl @luna-generic.Semiring for Decimal
pub impl @luna-generic.Zero for Decimal
pub impl Add for Decimal
pub impl Compare for Decimal
pub impl Div for Decimal
pub impl Eq for Decimal
pub impl Mul for Decimal
pub impl Neg for Decimal
pub impl Show for Decimal
pub impl Sub for Decimal

pub struct DecimalContext {
  // private fields
} derive(Eq)
pub fn DecimalContext::clamp(Self) -> Bool
pub fn DecimalContext::decimal128() -> Self
pub fn DecimalContext::decimal32() -> Self
pub fn DecimalContext::decimal64() -> Self
pub fn DecimalContext::decimal_rounding(Self) -> DecimalRoundingMode
pub fn DecimalContext::e_max(Self) -> Int
pub fn DecimalContext::e_min(Self) -> Int
pub fn DecimalContext::equal(Self, Self) -> Bool
pub fn DecimalContext::exact() -> Self
pub fn DecimalContext::extended(Self) -> Bool
pub fn DecimalContext::from_arithmetic_context(@arithmetic.ArithmeticContext) -> Self
pub fn DecimalContext::ieee754(Self) -> Self
pub fn DecimalContext::is754version2019(Self) -> Bool
pub fn DecimalContext::new(precision? : Int, rounding? : @arithmetic.RoundingMode, decimal_rounding? : DecimalRoundingMode, e_min? : Int, e_max? : Int, clamp? : Bool, extended? : Bool, tininess? : DecimalTininessDetection) -> Self
pub fn DecimalContext::not_equal(Self, Self) -> Bool
pub fn DecimalContext::precision(Self) -> Int
pub fn DecimalContext::rounding(Self) -> @arithmetic.RoundingMode
pub fn DecimalContext::tininess(Self) -> DecimalTininessDetection
pub fn DecimalContext::try_new(precision? : Int, rounding? : @arithmetic.RoundingMode, decimal_rounding? : DecimalRoundingMode, e_min? : Int, e_max? : Int, clamp? : Bool, extended? : Bool, tininess? : DecimalTininessDetection) -> Result[Self, @arithmetic.ArithmeticError]
pub fn DecimalContext::with_rounding(Self, @arithmetic.RoundingMode) -> Self
pub fn DecimalContext::with_tininess(Self, DecimalTininessDetection) -> Self

pub struct DecimalFlags {
  inexact : Bool
  rounded : Bool
  lost_digits : Bool
  invalid_operation : Bool
  division_by_zero : Bool
  overflow : Bool
  underflow : Bool
  subnormal : Bool
  clamped : Bool
  conversion_syntax : Bool
  division_impossible : Bool
  division_undefined : Bool
  invalid_context : Bool
} derive(Eq)
pub fn DecimalFlags::combine(Self, Self) -> Self
pub fn DecimalFlags::contains(Self, DecimalSignal) -> Bool
pub fn DecimalFlags::equal(Self, Self) -> Bool
pub fn DecimalFlags::has_error(Self) -> Bool
pub fn DecimalFlags::new() -> Self
pub fn DecimalFlags::not_equal(Self, Self) -> Bool

pub struct DecimalInterchange {
  // private fields
}
pub fn DecimalInterchange::canonical(Self) -> Self
pub fn DecimalInterchange::copy(Self) -> Self
pub fn DecimalInterchange::copy_abs(Self) -> Self
pub fn DecimalInterchange::copy_negate(Self) -> Self
pub fn DecimalInterchange::copy_sign(Self, Self) -> Self
pub fn DecimalInterchange::encoding(Self) -> DecimalInterchangeEncoding
pub fn DecimalInterchange::format(Self) -> DecimalInterchangeFormat
pub fn DecimalInterchange::from_decimal(Decimal, DecimalInterchangeFormat) -> (Self, DecimalFlags)
pub fn DecimalInterchange::from_decimal_with_encoding(Decimal, DecimalInterchangeFormat, DecimalInterchangeEncoding) -> (Self, DecimalFlags)
pub fn DecimalInterchange::from_hex(String, DecimalInterchangeFormat) -> Self?
pub fn DecimalInterchange::from_hex_with_encoding(String, DecimalInterchangeFormat, DecimalInterchangeEncoding) -> Self?
pub fn DecimalInterchange::is_canonical(Self) -> Bool
pub fn DecimalInterchange::to_decimal(Self) -> Decimal
pub fn DecimalInterchange::to_decimal_ctx(Self) -> (Decimal, DecimalFlags)
pub fn DecimalInterchange::to_hex(Self) -> String

pub(all) enum DecimalInterchangeEncoding {
  DPD
  BID
} derive(Eq)
pub fn DecimalInterchangeEncoding::equal(Self, Self) -> Bool
pub fn DecimalInterchangeEncoding::not_equal(Self, Self) -> Bool

pub(all) enum DecimalInterchangeFormat {
  Decimal32
  Decimal64
  Decimal128
} derive(Eq)
pub fn DecimalInterchangeFormat::context(Self) -> DecimalContext
pub fn DecimalInterchangeFormat::equal(Self, Self) -> Bool
pub fn DecimalInterchangeFormat::not_equal(Self, Self) -> Bool

pub(all) enum DecimalRoundingMode {
  HalfEven
  HalfUp
  HalfDown
  Down
  Ceiling
  Floor
  Up
  ZeroFiveUp
} derive(Eq)
pub fn DecimalRoundingMode::equal(Self, Self) -> Bool
pub fn DecimalRoundingMode::from_arithmetic(@arithmetic.RoundingMode) -> Self
pub fn DecimalRoundingMode::not_equal(Self, Self) -> Bool
pub fn DecimalRoundingMode::to_arithmetic(Self) -> @arithmetic.RoundingMode?

pub(all) enum DecimalSignal {
  ConversionSyntax
  DivisionByZero
  DivisionImpossible
  DivisionUndefined
  InvalidContext
  InvalidOperation
  Overflow
  Underflow
  Subnormal
  Inexact
  Rounded
  Clamped
  LostDigits
} derive(Eq)
pub fn DecimalSignal::equal(Self, Self) -> Bool
pub fn DecimalSignal::not_equal(Self, Self) -> Bool

pub(all) enum DecimalTininessDetection {
  BeforeRounding
  AfterRounding
} derive(Eq)
pub fn DecimalTininessDetection::equal(Self, Self) -> Bool
pub fn DecimalTininessDetection::not_equal(Self, Self) -> Bool

// Type aliases

// Traits