Lean 语言参考手册

20.6. 浮点数🔗

浮点数是对实数的一种近似,并且能在计算机硬件中高效实现。 使用浮点数的计算通常非常高效;不过,它们逼近实数的方式本身很复杂,存在许多边界情况。 IEEE 754 标准定义了现代计算机使用的浮点格式,它允许硬件设计者和编程语言实现做出某些选择,而真实系统在这些细节上并不完全相同。 硬件、操作系统、C 编译器、库版本乃至编译选项的任意组合,都可能导致不同的行为。 例如,表示结果未定义的 NaN 就有许多不同的位表示,而且有些平台在“两个 NaN 相加时究竟返回哪个 NaN”这一点上并不一致。

为了能够对浮点数进行推理,Lean 暴露出了一个用于证明的 Float 逻辑模型。 具体来说,FloatFloat32 都是围绕该逻辑模型实现的包装器。 在编译后的代码中,这个逻辑模型会被高效的原生代码取代。 平台之间的差异通过两种方式解决:一是选择特定表示(例如,只要某个运算请求位表示,所有 NaN 值都会被替换为单一的规范 NaN),二是只为所有受支持平台上实现完全一致的那一部分浮点运算建立模型。 其他运算(例如三角函数)则在 Lean 的逻辑中表示为不透明函数。

该逻辑模型已在所有受支持平台上与浮点运算进行了广泛的经验性测试。 只要 FFI 代码不修改浮点环境,Lean 运行时的浮点原语就符合该模型的规约。

🔗结构体
Float : Type
Float : Type

64 位浮点数。

Float 对应 IEEE 754 的 binary64 格式(C 中的 double 或 Rust 中的 f64)。 浮点数以有限形式表示实数的一个子集,并扩充了额外的“哨兵”值,用于表示未定义结果、无穷结果以及彼此分离的正零和负零。浮点算术会把结果舍入到可表示的数,从而近似实数上的相应运算,并传播错误值与无穷值。

浮点数包括次正规数。 其特殊值包括:

  • NaN,表示一类“非数”值,由零除以零等运算产生;以及

  • Inf-Inf,分别表示正无穷与负无穷,由非零值除以零产生。

与其他底层类型一样,Lean 编译器会特殊处理 Float,使其对应 C 的 double 类型。从 Lean 逻辑的角度看,Float 等价于 Float.Model(通过函数 Float.toModelFloat.ofModel),而后者本身是 UInt64 的子类型。Float 上的一些运算根据其 Float.Model 对应项定义,另一些运算则对 Lean 内核不透明。

Float.ofModel

Float.Model 构造 Float

toModel : Float.Model

Float 转换为 Float.Model

🔗结构体
Float32 : Type
Float32 : Type

32 位浮点数。

Float32 对应 IEEE 754 的 binary32 格式(C 中的 float 或 Rust 中的 f32)。 浮点数以有限形式表示实数的一个子集,并扩充了额外的“哨兵”值,用于表示未定义结果、无穷结果以及彼此分离的正零和负零。浮点算术会把结果舍入到可表示的数,从而近似实数上的相应运算,并传播错误值与无穷值。

浮点数包括次正规数。 其特殊值包括:

  • NaN,表示一类“非数”值,由零除以零等运算产生;以及

  • Inf-Inf,分别表示正无穷与负无穷,由非零值除以零产生。

与其他底层类型一样,Lean 编译器会特殊处理 Float32,使其对应 C 的 float 类型。从 Lean 逻辑的角度看,Float32 等价于 Float32.Model(通过函数 Float32.toModelFloat32.ofModel),而后者本身是 UInt32 的子类型。Float32 上的一些运算根据其 Float32.Model 对应项定义,另一些运算则对 Lean 内核不透明。

Float32.ofModel

Float32.Model 构造 Float32

toModel : Float32.Model

Float32 转换为 Float32.Model

20.6.1. 逻辑模型🔗

Lean 提供两种浮点类型:Float 表示 64 位浮点值,而 Float32 表示 32 位浮点值。 Float 的精度不会随着 Lean 所运行的平台而变化。

20.6.1.1. 模型细节🔗

FloatFloat32 的逻辑模型由带有有效性谓词的无符号整数组成。 每个已定义的运算都会先把该整数解释为 Float.Model.UnpackedFloat,这是一个不依赖具体位宽的更高层模型。 然后,用 UnpackedFloat 来实现该运算,并将结果重新打包。 这些定义构成了一个用于推理的逻辑规约。 尽管它们可以执行,但运行速度会明显慢于原生代码。 并非所有运算都有定义;有些运算则被表示为不透明函数,其行为无法在 Lean 的逻辑中进行推理。

该模型并不打算作为更大型浮点数库的基础。 它仅用于支持 Lean 中可用的推理工具,并不适合更大规模的开发。 不要把这个模型当作更大型浮点数库的基础。 正确做法是实现一个合适的模型,证明其运算与该模型上的运算等价,然后借助这种等价转移引理。

🔗结构体

Float 类型的逻辑模型。

它定义为 UInt64 的一种类型,并附加限制:编码 NaN 的位模式必须恰好是选定的规范 NaN

大多数 Float.Model 函数会先把 Float.Model 解包为归纳类型 UnpackedFloat,在那里执行运算,然后把结果重新打包成 Float.Model

本开发并不以成为通用浮点数库的基础为目标,也不打算直接为它编写任何引理。希望获得浮点数库的用户应完全独立地开发这样的库;希望证明涉及 Float 的程序性质的用户,则应证明此处定义的运算等价于独立库中定义的运算,再把该库的引理转移到 FloatFloat32 类型上。

Float.Model.mk
toBits : UInt64

Float.Model 的底层位模式。

valid : Float.Model.Format.binary64.Valid self.toBits.toBitVec

底层位模式按照 IEEE binary64 格式是有效的。

🔗结构体

Float32 类型的逻辑模型。

它定义为 UInt32 的一种类型,并附加限制:编码 NaN 的位模式必须恰好是选定的规范 NaN

大多数 Float32.Model 函数会先把 Float32.Model 解包为归纳类型 UnpackedFloat,在那里执行运算,然后把结果重新打包成 Float32.Model

本开发并不以成为通用浮点数库的基础为目标,也不打算直接为它编写任何引理。希望获得浮点数库的用户应完全独立地开发这样的库;希望证明涉及 Float32 的程序性质的用户,则应证明此处定义的运算等价于独立库中定义的运算,再把该库的引理转移到 FloatFloat32 类型上。

Float32.Model.mk
toBits : UInt32

Float32.Model 的底层位模式。

valid : Float.Model.Format.binary32.Valid self.toBits.toBitVec

底层位模式按照 IEEE binary32 格式是有效的。

🔗定义

UnpackedFloat 打包为相应的 Float.Model。 只有当该浮点数已经按 Format.binary64 格式正确舍入时,此运算的结果才有意义。

🔗定义

UnpackedFloat 打包为相应的 Float32.Model。 只有当该浮点数已经按 Format.binary32 格式正确舍入时,此运算的结果才有意义。

🔗归纳类型

一种表示浮点数的归纳类型,其构造子分别表示带符号无穷、不带载荷的非数、带符号零,以及由符号、正自然数尾数和整数指数构成的有限浮点数。

有限浮点数在此格式中没有唯一表示:尾数乘以二、指数减一后,所得有限浮点数仍表示同一个有理数。

对于给定的 Format,若指数等于该格式规定的 targetExponent,就称解包后的浮点数处于规范形式。UnpackedFloat 上的某些运算(例如 compare)假定所有输入都对同一格式处于规范形式。

请注意,对给定格式处于规范形式的解包浮点数未必能由该格式实际表示,因为指数可能太大而无法容纳。此时,pack 函数会使浮点数上溢为无穷。

此类型仅用于支持 Float.ModelFloat32.Model。本开发并不以成为通用浮点数库的基础为目标,也不打算直接为它编写任何引理。希望获得浮点数库的用户应完全独立地开发这样的库;希望证明涉及 Float 的程序性质的用户,则应证明此处定义的运算等价于独立库中定义的运算,再把该库的引理转移到 FloatFloat32 类型上。

Float.Model.UnpackedFloat.infinity
  (sign : Float.Model.UnpackedFloat.Sign) :
  Float.Model.UnpackedFloat

带符号无穷。

Float.Model.UnpackedFloat.notANumber :
  Float.Model.UnpackedFloat

非数。此格式中的 NaN 不附带载荷。

Float.Model.UnpackedFloat.zero
  (sign : Float.Model.UnpackedFloat.Sign) :
  Float.Model.UnpackedFloat

带符号零。

Float.Model.UnpackedFloat.finite
  (sign : Float.Model.UnpackedFloat.Sign) (mantissa : Nat)
  (exponent : Int) (mantissa_pos : 0 < mantissa) :
  Float.Model.UnpackedFloat

由符号位、正自然数尾数和指数构成的有限浮点数。

20.6.1.2. 模型运算🔗

下列运算为浮点值提供了规约。 其他运算符则表示为不透明函数,不能在内核中规约。

🔗定义

计算两个浮点数之和,并按照给定规约舍入结果。

🔗定义

计算两个浮点数之差,并按照给定规约舍入结果。

🔗定义

计算两个浮点数之积,并按照给定规约舍入结果。

🔗定义

计算两个浮点数之商,并按照给定规约舍入结果。

🔗定义

计算浮点数的平方根,并按照给定规约舍入结果。

🔗定义

返回 true,当该浮点数表示实数,即它既非无穷也非 NaN

🔗定义

按照 IEEE 规定计算两个浮点数的次序。返回 Option Ordering,以体现 NaN 与任何值都不可比较这一事实。正零与负零也视为相等。

重要:仅当两个输入都对同一格式处于规范形式时,此运算才能正确工作(详情参见 UnpackedFloat 的文档字符串)。

🔗定义

按照 IEEE 规则判断 a 是否等于 b

该关系不具自反性。

🔗定义

按照 IEEE 规则判断 a 是否小于 b

这不是全序。

🔗定义

按照 IEEE 规则判断 a 是否小于或等于 b

这不是全序,并且 不具自反性。

🔗定义

Nat 转换为 UnpackedFloat;输入为零时返回正零。

🔗定义

Int 转换为 UnpackedFloat;输入为零时返回正零。

🔗定义

计算 m * 10 ^ e

🔗定义

UnpackedFloat 转换为 Int8:截去小数点后的部分,把 NaN 转换为 0,并将越界值和无穷值钳制到范围内。

🔗定义

Int8 转换为 UnpackedFloat;输入为零时返回正零。

🔗定义

UnpackedFloat 转换为 Int16:截去小数点后的部分,把 NaN 转换为 0,并将越界值和无穷值钳制到范围内。

🔗定义

Int16 转换为 UnpackedFloat;输入为零时返回正零。

🔗定义

UnpackedFloat 转换为 Int32:截去小数点后的部分,把 NaN 转换为 0,并将越界值和无穷值钳制到范围内。

🔗定义

Int32 转换为 UnpackedFloat;输入为零时返回正零。

🔗定义

UnpackedFloat 转换为 Int64:截去小数点后的部分,把 NaN 转换为 0,并将越界值和无穷值钳制到范围内。

🔗定义

Int64 转换为 UnpackedFloat;输入为零时返回正零。

🔗定义

UnpackedFloat 转换为 ISize:截去小数点后的部分,把 NaN 转换为 0,并将越界值和无穷值钳制到范围内。

🔗定义

ISize 转换为 UnpackedFloat;输入为零时返回正零。

🔗定义

UnpackedFloat 转换为 UInt8:截去小数点后的部分,把 NaN 转换为 0,并将越界值和无穷值钳制到范围内。

🔗定义

UInt8 转换为 UnpackedFloat;输入为零时返回正零。

🔗定义

UnpackedFloat 转换为 UInt16:截去小数点后的部分,把 NaN 转换为 0,并将越界值和无穷值钳制到范围内。

🔗定义

UInt16 转换为 UnpackedFloat;输入为零时返回正零。

🔗定义

UnpackedFloat 转换为 UInt32:截去小数点后的部分,把 NaN 转换为 0,并将越界值和无穷值钳制到范围内。

🔗定义

UInt32 转换为 UnpackedFloat;输入为零时返回正零。

🔗定义

UnpackedFloat 转换为 UInt64:截去小数点后的部分,把 NaN 转换为 0,并将越界值和无穷值钳制到范围内。

🔗定义

UInt64 转换为 UnpackedFloat;输入为零时返回正零。

🔗定义

UnpackedFloat 转换为 USize:截去小数点后的部分,把 NaN 转换为 0,并将越界值和无穷值钳制到范围内。

🔗定义

USize 转换为 UnpackedFloat;输入为零时返回正零。

内核推理

Lean 内核可以按句法相等比较类型为 Float 的表达式,因此 0.0 与其自身定义等价。

example : (0.0 : Float) = (0.0 : Float) := 0.0 = 0.0 All goals completed! 🐙

此外,如果若干项需要经过规约后才能在句法上相等,那么只要它们只使用了在 Lean 逻辑中建模的运算,内核也可以检查它们:

example : (0.0 : Float) = (0.0 + 0.0 : Float) := 0.0 = 0.0 + 0.0 All goals completed! 🐙

内核无法规约使用了未被直接建模运算的项,例如三角函数:

example : (0.0 : Float).sin = (0.0 : Float) := Float.sin 0.0 = 0.0 Tactic `rfl` failed: The left-hand side Float.sin 0.0 is not definitionally equal to the right-hand side 0.0 Float.sin 0.0 = 0.0Float.sin 0.0 = 0.0
Tactic `rfl` failed: The left-hand side
  Float.sin 0.0
is not definitionally equal to the right-hand side
  0.0

Float.sin 0.0 = 0.0

不过,native_decide 策略可以调用 Lean 在运行时程序中使用的底层平台浮点原语:

theorem Float.sin_zero_eq_zero : ((0.0 : Float).sin == (0.0 : Float)) = true := (sin 0.0 == 0.0) = true All goals completed! 🐙

该策略会把判定过程作为编译后的原生代码执行。 这意味着,除内核外,还必须信任 Lean 编译器、解释器以及内建运算符的底层实现。 为了精确地说明这一依赖,该策略会生成公理 Float.sin_zero_eq_zero._native.native_decide.ax_1

'Float.sin_zero_eq_zero' depends on axioms: [propext, Classical.choice, Quot.sound, Float.sin_zero_eq_zero._native.native_decide.ax_1]#print axioms Float.sin_zero_eq_zero
'Float.sin_zero_eq_zero' depends on axioms: [propext,
 Classical.choice,
 Quot.sound,
 Float.sin_zero_eq_zero._native.native_decide.ax_1]
浮点相等并非自反

浮点运算可能产生表示结果未定义的 NaN 值。 这些值彼此不可比较;特别地,凡是涉及 NaN 的比较都会返回 false,包括相等比较。

false#eval ((0.0 : Float) / 0.0) == ((0.0 : Float) / 0.0)
浮点相等不是同余关系

把同一个函数应用到两个相等的浮点数上,结果未必仍然相等。 特别地,正零与负零是不同的值,但浮点相等会把它们判为相等;然而用正零或负零作除数时,却会分别得到正无穷或负无穷。

def neg0 : Float := -0.0 def pos0 : Float := 0.0 (true, false)#eval (neg0 == pos0, 1.0 / neg0 == 1.0 / pos0)
(true, false)

20.6.2. 语法🔗

Lean 没有专门的浮点数字面量。 相反,浮点数字面量是通过 OfScientificNeg 类型类的相应实例来解析的。

浮点数字面量

(-2.523 : Float)

是下列写法的语法糖:

(Neg.neg (OfScientific.ofScientific 22523 true 4) : Float)

而项

(413.52 : Float32)

是下列写法的语法糖:

(OfScientific.ofScientific 41352 true 2 : Float32)

20.6.3. 接口参考🔗

20.6.3.1. 性质🔗

浮点数属于以下三类之一:

  • 有限数是普通的浮点值。

  • 无穷大可能是正的也可能是负的,它们来源于除以零。

  • NaN 不是数,它来源于其他未定义运算,例如对负数取平方根。

🔗定义

检查浮点数是否为正无穷或负无穷,而不是有限数或 NaN

此函数具有基于 Float.Model 的逻辑模型,并被编译为 C 运算符 isinf

🔗定义

检查浮点数是否为正无穷或负无穷,而不是有限数或 NaN

此函数具有基于 Float32.Model 的逻辑模型,并被编译为 C 运算符 isinf

🔗定义

检查浮点数是否为 NaN(“非数”)值。

NaN 值由原本可能成为错误的运算产生,例如零除以零。

此函数返回 true 当且仅当输入在命题上等于 Float.nan

此函数具有基于 Float.Model 的逻辑模型,并被编译为 C 运算符 isnan

🔗定义

检查浮点数是否为 NaN(“非数”)值。

NaN 值由原本可能成为错误的运算产生,例如零除以零。

此函数返回 true 当且仅当输入在命题上等于 Float32.nan

此函数具有基于 Float32.Model 的逻辑模型,并被编译为 C 运算符 isnan

🔗定义

检查浮点数是否有限,即它是正规数、次正规数或零,而不是无穷或 NaN

此函数具有基于 Float.Model 的逻辑模型,并被编译为 C 运算符 isfinite

🔗定义

检查浮点数是否有限,即它是正规数、次正规数或零,而不是无穷或 NaN

此函数具有基于 Float32.Model 的逻辑模型,并被编译为 C 运算符 isfinite

20.6.3.2. 转换🔗

🔗定义

逐位转换为 UInt64。把 Float 解释为 UInt64,忽略数值,仅将 Float 的位模式视为 UInt64

在所有受支持平台上,FloatUInt64 的字节序相同。IEEE 754 非常精确地规定了浮点数的位布局。

此函数不同于 Float.toUInt64;后者试图保持数值,而不是重新解释位模式。

🔗定义

逐位转换为 UInt32。把 Float32 解释为 UInt32,忽略数值,仅将 Float32 的位模式视为 UInt32

在所有受支持平台上,Float32UInt32 的字节序相同。IEEE 754 非常精确地规定了浮点数的位布局。

此函数不同于 Float.toUInt32;后者试图保持数值,而不是重新解释位模式。

🔗定义

UInt64 逐位转换。把 UInt64 解释为 Float,忽略数值,仅将 UInt64 的位模式视为 Float

在所有受支持平台上,FloatUInt64 的字节序相同。IEEE 754 非常精确地规定了浮点数的位布局。

此函数具有基于 Float.Model 的逻辑模型。

🔗定义

UInt32 逐位转换。把 UInt32 解释为 Float32,忽略数值,仅将 UInt32 的位模式视为 Float32

在所有受支持平台上,Float32UInt32 的字节序相同。IEEE 754 非常精确地规定了浮点数的位布局。

此函数具有基于 Float32.Model 的逻辑模型。

🔗不透明定义

把 64 位浮点数转换为 32 位浮点数。 这可能损失精度。

此函数不在内核中规约。

🔗不透明定义

把 32 位浮点数转换为 64 位浮点数。

此函数不在内核中规约。

🔗不透明定义

把浮点数转换为字符串。

此函数不在内核中规约。

🔗不透明定义

把浮点数转换为字符串。

此函数不在内核中规约。

🔗定义

把浮点数转换为8 位无符号整数。

若给定的 Float 非负,则向下舍入,把值截断为正整数,并钳制到 UInt8 的范围。返回 0,当 Float 为负数或 NaN;若浮点数大于该最大值,则返回最大的 UInt8 值(即 UInt8.size - 1)。

此函数具有基于 Float.Model 的逻辑模型。

🔗定义

把浮点数向零舍入,截断为最接近的8 位有符号整数。

Float 大于 Int8 的最大值(包括 Inf),则返回 Int8 的最大值(即 Int8.maxValue)。若它小于 Int8 的最小值(包括 -Inf),则返回 Int8 的最小值(即 Int8.minValue)。若它为 NaN,则返回 0

此函数具有基于 Float.Model 的逻辑模型。

🔗定义

把浮点数转换为8 位无符号整数。

若给定的 Float32 非负,则向下舍入,把值截断为正整数,并钳制到 UInt8 的范围。返回 0,当 Float32 为负数或 NaN;若浮点数大于该最大值,则返回最大的 UInt8 值(即 UInt8.size - 1)。

此函数具有基于 Float32.Model 的逻辑模型。

🔗定义

把浮点数向零舍入,截断为最接近的8 位有符号整数。

Float 大于 Int8 的最大值(包括 Inf),则返回 Int8 的最大值(即 Int8.maxValue)。若它小于 Int8 的最小值(包括 -Inf),则返回 Int8 的最小值(即 Int8.minValue)。若它为 NaN,则返回 0

此函数具有基于 Float32.Model 的逻辑模型。

🔗定义

把浮点数转换为16 位无符号整数。

若给定的 Float 非负,则向下舍入,把值截断为正整数,并钳制到 UInt16 的范围。返回 0,当 Float 为负数或 NaN;若浮点数大于该最大值,则返回最大的 UInt16 值(即 UInt16.size - 1)。

此函数具有基于 Float.Model 的逻辑模型。

🔗定义

把浮点数向零舍入,截断为最接近的16 位有符号整数。

Float 大于 Int16 的最大值(包括 Inf),则返回 Int16 的最大值(即 Int16.maxValue)。若它小于 Int16 的最小值(包括 -Inf),则返回 Int16 的最小值(即 Int16.minValue)。若它为 NaN,则返回 0

此函数具有基于 Float.Model 的逻辑模型。

🔗定义

把浮点数转换为16 位无符号整数。

若给定的 Float32 非负,则向下舍入,把值截断为正整数,并钳制到 UInt16 的范围。返回 0,当 Float32 为负数或 NaN;若浮点数大于该最大值,则返回最大的 UInt16 值(即 UInt16.size - 1)。

此函数具有基于 Float32.Model 的逻辑模型。

🔗定义

把浮点数向零舍入,截断为最接近的16 位有符号整数。

Float 大于 Int16 的最大值(包括 Inf),则返回 Int16 的最大值(即 Int16.maxValue)。若它小于 Int16 的最小值(包括 -Inf),则返回 Int16 的最小值(即 Int16.minValue)。若它为 NaN,则返回 0

此函数具有基于 Float32.Model 的逻辑模型。

🔗定义

把浮点数转换为32 位无符号整数。

若给定的 Float 非负,则向下舍入,把值截断为正整数,并钳制到 UInt32 的范围。返回 0,当 Float 为负数或 NaN;若浮点数大于该最大值,则返回最大的 UInt32 值(即 UInt32.size - 1)。

此函数具有基于 Float.Model 的逻辑模型。

🔗定义

把浮点数转换为32 位无符号整数。

若给定的 Float32 非负,则向下舍入,把值截断为正整数,并钳制到 UInt32 的范围。返回 0,当 Float32 为负数或 NaN;若浮点数大于该最大值,则返回最大的 UInt32 值(即 UInt32.size - 1)。

此函数具有基于 Float32.Model 的逻辑模型。

🔗定义

把浮点数向零舍入,截断为最接近的32 位有符号整数。

Float 大于 Int32 的最大值(包括 Inf),则返回 Int32 的最大值(即 Int32.maxValue)。若它小于 Int32 的最小值(包括 -Inf),则返回 Int32 的最小值(即 Int32.minValue)。若它为 NaN,则返回 0

此函数具有基于 Float.Model 的逻辑模型。

🔗定义

把浮点数向零舍入,截断为最接近的32 位有符号整数。

Float 大于 Int32 的最大值(包括 Inf),则返回 Int32 的最大值(即 Int32.maxValue)。若它小于 Int32 的最小值(包括 -Inf),则返回 Int32 的最小值(即 Int32.minValue)。若它为 NaN,则返回 0

此函数具有基于 Float32.Model 的逻辑模型。

🔗定义

把浮点数转换为64 位无符号整数。

若给定的 Float 非负,则向下舍入,把值截断为正整数,并钳制到 UInt64 的范围。返回 0,当 Float 为负数或 NaN;若浮点数大于该最大值,则返回最大的 UInt64 值(即 UInt64.size - 1)。

此函数具有基于 Float.Model 的逻辑模型。

🔗定义

把浮点数向零舍入,截断为最接近的64 位有符号整数。

Float 大于 Int64 的最大值(包括 Inf),则返回 Int64 的最大值(即 Int64.maxValue)。若它小于 Int64 的最小值(包括 -Inf),则返回 Int64 的最小值(即 Int64.minValue)。若它为 NaN,则返回 0

此函数具有基于 Float.Model 的逻辑模型。

🔗定义

把浮点数转换为64 位无符号整数。

若给定的 Float32 非负,则向下舍入,把值截断为正整数,并钳制到 UInt64 的范围。返回 0,当 Float32 为负数或 NaN;若浮点数大于该最大值,则返回最大的 UInt64 值(即 UInt64.size - 1)。

此函数具有基于 Float32.Model 的逻辑模型。

🔗定义

把浮点数向零舍入,截断为最接近的64 位有符号整数。

Float 大于 Int64 的最大值(包括 Inf),则返回 Int64 的最大值(即 Int64.maxValue)。若它小于 Int64 的最小值(包括 -Inf),则返回 Int64 的最小值(即 Int64.minValue)。若它为 NaN,则返回 0

此函数具有基于 Float32.Model 的逻辑模型。

🔗定义

把浮点数转换为机器字长无符号整数。

若给定的 Float 非负,则向下舍入,把值截断为正整数,并钳制到 USize 的范围。返回 0,当 Float 为负数或 NaN;若浮点数大于该最大值,则返回最大的 USize 值(即 USize.size - 1)。

此函数具有基于 Float.Model 的逻辑模型。

🔗定义

把浮点数转换为机器字长无符号整数。

若给定的 Float32 非负,则向下舍入,把值截断为正整数,并钳制到 USize 的范围。返回 0,当 Float32 为负数或 NaN;若浮点数大于该最大值,则返回最大的 USize 值(即 USize.size - 1)。

此函数具有基于 Float32.Model 的逻辑模型。

🔗定义

把浮点数向零舍入,截断为最接近的机器字长有符号整数。

Float 大于 ISize 的最大值(包括 Inf),则返回 ISize 的最大值(即 ISize.maxValue)。若它小于 ISize 的最小值(包括 -Inf),则返回 ISize 的最小值(即 ISize.minValue)。若它为 NaN,则返回 0

此函数具有基于 Float.Model 的逻辑模型。

🔗定义

把浮点数向零舍入,截断为最接近的机器字长有符号整数。

Float 大于 ISize 的最大值(包括 Inf),则返回 ISize 的最大值(即 ISize.maxValue)。若它小于 ISize 的最小值(包括 -Inf),则返回 ISize 的最小值(即 ISize.minValue)。若它为 NaN,则返回 0

此函数具有基于 Float32.Model 的逻辑模型。

🔗定义

把整数转换为最接近的 64 位浮点数;若超出 Float 的范围,则转换为正无穷或负无穷浮点值。

🔗定义

把整数转换为最接近的 32 位浮点数;若超出 Float32 的范围,则转换为正无穷或负无穷浮点值。

🔗定义

把自然数转换为最接近的 64 位浮点数;若超出 Float 的范围,则转换为无穷浮点值。

🔗定义

把自然数转换为最接近的 32 位浮点数;若超出 Float32 的范围,则转换为无穷浮点值。

🔗不透明定义

把给定浮点数 x 拆分为有效数/指数对 (s, i),满足 x = s * 2^i,其中 s (-1;-0.5] [0.5; 1)。若 x 不是有限数,则返回未定义值。

此函数不在内核中规约。编译后代码由 C 函数 frexp 实现。

🔗不透明定义

把给定浮点数 x 拆分为有效数/指数对 (s, i),满足 x = s * 2^i,其中 s (-1;-0.5] [0.5; 1)。若 x 不是有限数,则返回未定义值。

此函数不在内核中规约。编译后代码由 C 函数 frexp 实现。

20.6.3.3. 比较🔗

🔗定义
Float.beq (a b : Float) : Bool
Float.beq (a b : Float) : Bool

按照 IEEE 754 检查两个浮点数是否相等。

浮点相等与命题等式并不对应。特别地,由于 NaN != NaN,它不具自反性;又由于 0.0 == -0.01.0 / 0.0 != 1.0 / -0.0,它也不是同余关系。

此函数不在内核中规约,并被编译为 C 相等运算符。

🔗定义

按照 IEEE 754 检查两个浮点数是否相等。

浮点相等与命题等式并不对应。特别地,由于 NaN != NaN,它不具自反性;又由于 0.0 == -0.01.0 / 0.0 != 1.0 / -0.0,它也不是同余关系。

此函数不在内核中规约,并被编译为 C 相等运算符。

20.6.3.3.1. 不等关系🔗

不等关系的判定过程在逻辑中是不透明常量。 它们只能借助 Lean.ofReduceBool 公理来使用,例如通过 native_decide 策略。

🔗定义

浮点数的非严格不等关系。通常通过 运算符使用。

🔗定义

浮点数的非严格不等关系。通常通过 运算符使用。

🔗定义

浮点数的严格不等关系。通常通过 < 运算符使用。

🔗定义

浮点数的严格不等关系。通常通过 < 运算符使用。

🔗定义

比较两个浮点数是否满足非严格不等关系。

此函数不在内核中规约,并被编译为 C 不等运算符。

🔗定义

比较两个浮点数是否满足非严格不等关系。

此函数不在内核中规约,并被编译为 C 不等运算符。

🔗定义

比较两个浮点数是否满足严格不等关系。

此函数不在内核中规约,并被编译为 C 不等运算符。

🔗定义

比较两个浮点数是否满足严格不等关系。

此函数不在内核中规约,并被编译为 C 不等运算符。

20.6.3.4. 算术🔗

浮点值上的算术运算通常通过 Add FloatSub FloatMul FloatDiv FloatHomogeneousPow Float 实例来调用,Float32 也有对应实例。

🔗定义

按照 IEEE 754 将两个 64 位浮点数相加。通常通过 + 运算符使用。

此函数具有基于 Float.Model 的逻辑模型,并被编译为 C 加法运算符。

🔗定义

按照 IEEE 754 将两个 32 位浮点数相加。通常通过 + 运算符使用。

此函数具有基于 Float32.Model 的逻辑模型,并被编译为 C 加法运算符。

🔗定义

按照 IEEE 754 将两个 64 位浮点数相减。通常通过 - 运算符使用。

此函数具有基于 Float.Model 的逻辑模型,并被编译为 C 减法运算符。

🔗定义

按照 IEEE 754 将两个 32 位浮点数相减。通常通过 - 运算符使用。

此函数具有基于 Float32.Model 的逻辑模型,并被编译为 C 减法运算符。

🔗定义

按照 IEEE 754 将两个 64 位浮点数相乘。通常通过 * 运算符使用。

此函数具有基于 Float.Model 的逻辑模型,并被编译为 C 乘法运算符。

🔗定义

按照 IEEE 754 将两个 32 位浮点数相乘。通常通过 * 运算符使用。

此函数具有基于 Float32.Model 的逻辑模型,并被编译为 C 乘法运算符。

🔗定义

按照 IEEE 754 将两个 64 位浮点数相除。通常通过 / 运算符使用。

在 Lean 中,除以零通常得到零;但对 Float 而言,结果会是 Inf-InfNaN

此函数具有基于 Float.Model 的逻辑模型,并被编译为 C 除法运算符。

🔗定义

按照 IEEE 754 将两个 32 位浮点数相除。通常通过 / 运算符使用。

在 Lean 中,除以零通常得到零;但对 Float32 而言,结果会是 Inf-InfNaN

此函数具有基于 Float32.Model 的逻辑模型,并被编译为 C 除法运算符。

🔗不透明定义

把一个浮点数提升到另一个浮点数次幂。通常通过 ^ 运算符使用。

此函数不在内核中规约。编译后代码由 C 函数 pow 实现。

🔗不透明定义

把一个浮点数提升到另一个浮点数次幂。通常通过 ^ 运算符使用。

此函数不在内核中规约。编译后代码由 C 函数 powf 实现。

🔗不透明定义

计算浮点数的指数 e^x

此函数不在内核中规约。编译后代码由 C 函数 exp 实现。

🔗不透明定义

计算浮点数的指数 e^x

此函数不在内核中规约。编译后代码由 C 函数 expf 实现。

🔗不透明定义

计算浮点数以 2 为底的指数 2^x

此函数不在内核中规约。编译后代码由 C 函数 exp2 实现。

🔗不透明定义

计算浮点数以 2 为底的指数 2^x

此函数不在内核中规约。编译后代码由 C 函数 exp2f 实现。

20.6.3.4.1. 根🔗

对负数计算平方根会得到 NaN

🔗定义

计算浮点数的平方根。

此函数具有基于 Float.Model 的逻辑模型。编译后代码由 C 函数 sqrt 实现。

🔗定义

计算浮点数的平方根。

此函数具有基于 Float32.Model 的逻辑模型。编译后代码由 C 函数 sqrtf 实现。

🔗不透明定义

计算浮点数的立方根。

此函数不在内核中规约。编译后代码由 C 函数 cbrt 实现。

🔗不透明定义

计算浮点数的立方根。

此函数不在内核中规约。编译后代码由 C 函数 cbrtf 实现。

20.6.3.5. 对数🔗

🔗不透明定义

计算浮点数的自然对数 ln x

此函数不在内核中规约。编译后代码由 C 函数 log 实现。

🔗不透明定义

计算浮点数的自然对数 ln x

此函数不在内核中规约。编译后代码由 C 函数 logf 实现。

🔗不透明定义

计算浮点数以 10 为底的对数。

此函数不在内核中规约。编译后代码由 C 函数 log10 实现。

🔗不透明定义

计算浮点数以 10 为底的对数。

此函数不在内核中规约。编译后代码由 C 函数 log10f 实现。

🔗不透明定义

计算浮点数以 2 为底的对数。

此函数不在内核中规约。编译后代码由 C 函数 log2 实现。

🔗不透明定义

计算浮点数以 2 为底的对数。

此函数不在内核中规约。编译后代码由 C 函数 log2f 实现。

20.6.3.6. 缩放🔗

🔗不透明定义
Float.scaleB (x : Float) (i : Int) : Float
Float.scaleB (x : Float) (i : Int) : Float

高效计算 x * 2^i

此函数不在内核中规约。

🔗不透明定义

高效计算 x * 2^i

此函数不在内核中规约。

20.6.3.7. 取整🔗

🔗不透明定义

舍入到最近的整数;恰好位于中点时,向远离零的方向舍入。

此函数不在内核中规约。编译后代码由 C 函数 round 实现。

🔗不透明定义

舍入到最近的整数;恰好位于中点时,向远离零的方向舍入。

此函数不在内核中规约。编译后代码由 C 函数 roundf 实现。

🔗不透明定义

计算浮点数的下取整,即不大于给定数的最大整数。

此函数不在内核中规约。编译后代码由 C 函数 floor 实现。

示例:

🔗不透明定义

计算浮点数的下取整,即不大于给定数的最大整数。

此函数不在内核中规约。编译后代码由 C 函数 floorf 实现。

示例:

🔗不透明定义

计算浮点数的上取整,即不小于给定数的最小整数。

此函数不在内核中规约。编译后代码由 C 函数 ceil 实现。

示例:

🔗不透明定义

计算浮点数的上取整,即不小于给定数的最小整数。

此函数不在内核中规约。编译后代码由 C 函数 ceilf 实现。

示例:

20.6.3.8. 三角函数🔗

20.6.3.8.1. 正弦🔗

🔗不透明定义

计算浮点数的正弦(以弧度计)。

此函数不在内核中规约。编译后代码由 C 函数 sin 实现。

🔗不透明定义

计算浮点数的正弦(以弧度计)。

此函数不在内核中规约。编译后代码由 C 函数 sinf 实现。

🔗不透明定义

计算浮点数的双曲正弦。

此函数不在内核中规约。编译后代码由 C 函数 sinh 实现。

🔗不透明定义

计算浮点数的双曲正弦。

此函数不在内核中规约。编译后代码由 C 函数 sinhf 实现。

🔗不透明定义

计算浮点数的反正弦(正弦的反函数)(以弧度计)。

此函数不在内核中规约。编译后代码由 C 函数 asin 实现。

🔗不透明定义

计算浮点数的反正弦(正弦的反函数)(以弧度计)。

此函数不在内核中规约。编译后代码由 C 函数 asinf 实现。

🔗不透明定义

计算浮点数的反双曲正弦(双曲正弦的反函数)。

此函数不在内核中规约。编译后代码由 C 函数 asinh 实现。

🔗不透明定义

计算浮点数的反双曲正弦(双曲正弦的反函数)。

此函数不在内核中规约。编译后代码由 C 函数 asinhf 实现。

20.6.3.8.2. 余弦🔗

🔗不透明定义

计算浮点数的余弦(以弧度计)。

此函数不在内核中规约。编译后代码由 C 函数 cos 实现。

🔗不透明定义

计算浮点数的余弦(以弧度计)。

此函数不在内核中规约。编译后代码由 C 函数 cosf 实现。

🔗不透明定义

计算浮点数的双曲余弦。

此函数不在内核中规约。编译后代码由 C 函数 cosh 实现。

🔗不透明定义

计算浮点数的双曲余弦。

此函数不在内核中规约。编译后代码由 C 函数 coshf 实现。

🔗不透明定义

计算浮点数的反余弦(余弦的反函数)(以弧度计)。

此函数不在内核中规约。编译后代码由 C 函数 acos 实现。

🔗不透明定义

计算浮点数的反余弦(余弦的反函数)(以弧度计)。

此函数不在内核中规约。编译后代码由 C 函数 acosf 实现。

🔗不透明定义

计算浮点数的反双曲余弦(双曲余弦的反函数)。

此函数不在内核中规约。编译后代码由 C 函数 acosh 实现。

🔗不透明定义

计算浮点数的反双曲余弦(双曲余弦的反函数)。

此函数不在内核中规约。编译后代码由 C 函数 acoshf 实现。

20.6.3.8.3. 正切🔗

🔗不透明定义

计算浮点数的正切(以弧度计)。

此函数不在内核中规约。编译后代码由 C 函数 tan 实现。

🔗不透明定义

计算浮点数的正切(以弧度计)。

此函数不在内核中规约。编译后代码由 C 函数 tanf 实现。

🔗不透明定义

计算浮点数的双曲正切。

此函数不在内核中规约。编译后代码由 C 函数 tanh 实现。

🔗不透明定义

计算浮点数的双曲正切。

此函数不在内核中规约。编译后代码由 C 函数 tanhf 实现。

🔗不透明定义

计算浮点数的反正切(正切的反函数)(以弧度计)。

此函数不在内核中规约。编译后代码由 C 函数 atan 实现。

🔗不透明定义

计算浮点数的反正切(正切的反函数)(以弧度计)。

此函数不在内核中规约。编译后代码由 C 函数 atanf 实现。

🔗不透明定义

计算浮点数的反双曲正切(双曲正切的反函数)。

此函数不在内核中规约。编译后代码由 C 函数 atanh 实现。

🔗不透明定义

计算浮点数的反双曲正切(双曲正切的反函数)。

此函数不在内核中规约。编译后代码由 C 函数 atanhf 实现。

🔗不透明定义

计算 y / x 的反正切(以弧度计),结果范围为 -ππ。实参的符号决定结果所在的象限。

此函数不在内核中规约。编译后代码由 C 函数 atan2 实现。

🔗不透明定义

计算 y / x 的反正切(以弧度计),结果范围为 -ππ。实参的符号决定结果所在的象限。

此函数不在内核中规约。编译后代码由 C 函数 atan2f 实现。

20.6.3.9. 取负与绝对值🔗

🔗定义

计算浮点数的绝对值。

此函数具有基于 Float.Model 的逻辑模型。编译后代码由 C 函数 fabs 实现。

🔗定义

计算浮点数的绝对值。

此函数具有基于 Float32.Model 的逻辑模型。编译后代码由 C 函数 fabsf 实现。

🔗定义

按照 IEEE 754 对 64 位浮点数取负。通常通过前缀 - 运算符使用。

此函数具有基于 Float.Model 的逻辑模型,并被编译为 C 取负运算符。

🔗定义

按照 IEEE 754 对 32 位浮点数取负。通常通过前缀 - 运算符使用。

此函数具有基于 Float32.Model 的逻辑模型,并被编译为 C 取负运算符。