预定义浮点类型
以下浮点类型是预定义的:
float
常规的浮点类型,其大小曾与平台有关,但现在总是映射为 float64 。一般情况下应该使用这个类型。
floatXX
这种命名规则,是浮点类型附带 XX 位,表示位宽(例如: float64 是 64 位宽的浮点数)。
目前支持 float32 和 float64 ,字面值后缀为 ‘fXX 。
在具有不同种类的浮点类型的表达式中,会进行自动类型转换,详情见转换关系。 对于浮点类型进行的算术运算遵循 IEEE 标准。整数类型不会自动转换为浮点类型,反之亦然。
IEEE 标准定义了五种类型的浮点运算异常:
- 无效: 使用数学上无效的操作数运算, 例如 0.0/0.0, sqrt(-1.0), 和 log(-37.8).
- 除以零: 除数为零,且被除数是有限的非零数,例如 1.0 / 0.0 。
- 溢出: 运算产生的结果超出范围,例如,MAXDOUBLE + 0.0000000000001e308。
- 下溢: 运算产生的结果太小而无法表示为正常数字,例如,MINDOUBLE * MINDOUBLE。
- 不精确: 运算产生的结果无法用无限精度表示,例如,输入 2.0 / 3.0,log(1.1) 和 0.1。
IEEE 异常在执行期被忽略或映射到 Nim 异常: FloatInvalidOpDefect “浮点数无效缺陷” , FloatDivByZeroDefect “浮点数除零缺陷” , FloatOverflowDefect “浮点数溢出缺陷” , FloatUnderflowDefect “浮点数下溢缺陷” , 和 FloatInexactDefect “浮点数不精确缺陷” 。 这些异常继承自 FloatingPointDefect “浮点数缺陷” 基类。
Nim 提供了编译指示 nanChecks 和 infChecks 控制是否忽略 IEEE 异常或捕获 Nim 异常:
{.nanChecks: on, infChecks: on.}
var a = 1.0
var b = 0.0
echo b / b # 引发 FloatInvalidOpDefect
echo a / b # 引发 FloatOverflowDefect
在当前的实现中,绝不会引发 FloatDivByZeroError 和 FloatInexactError 。 FloatOverflowError 取代了 FloatDivByZeroError 。 另有 floatChecks 编译指示为 nanChecks 和 infChecks 的便捷方式。默认关闭 floatChecks 。
只有 +, -, *, / 这些运算符会受 floatChecks 编译指示影响。
在语义分析期间,应始终使用最大精度来评估浮点数,这表示在常量展开期间,表达式 0.09’f32 + 0.01’f32 == 0.09’f64 + 0.01’f64 的值为真。