Swift 3和4 -使用了浮点协议蓝图中的圆整(_:)方法
FloatingPoint协议(例如Double和Float遵循的协议)描绘了圆整(_:)方法
func圆润(_ rule: FloatingPointRoundingRule) ->自我
其中FloatingPointRoundingRule是枚举许多不同舍入规则的枚举:
case awayFromZero
Round to the closest allowed value whose magnitude is greater than or
equal to that of the source.
case down
Round to the closest allowed value that is less than or equal to the
source.
case toNearestOrAwayFromZero
Round to the closest allowed value; if two values are equally close,
the one with greater magnitude is chosen.
case toNearestOrEven
Round to the closest allowed value; if two values are equally close,
the even one is chosen.
case towardZero
Round to the closest allowed value whose magnitude is less than or
equal to that of the source.
case up
Round to the closest allowed value that is greater than or equal to
the source.
我们用@Suragch的精彩回答中类似的例子来展示这些不同的舍入选择。
.awayFromZero
四舍五入到最接近的允许值,其大小大于或等于源的大小;C函数之间没有直接的等价,因为这里分别使用self、cell或floor的符号作为self的正数和负数。
3.000.rounded(.awayFromZero) // 3.0
3.001.rounded(.awayFromZero) // 4.0
3.999.rounded(.awayFromZero) // 4.0
(-3.000).rounded(.awayFromZero) // -3.0
(-3.001).rounded(.awayFromZero) // -4.0
(-3.999).rounded(.awayFromZero) // -4.0
.down
等价于C层函数。
3.000.rounded(.down) // 3.0
3.001.rounded(.down) // 3.0
3.999.rounded(.down) // 3.0
(-3.000).rounded(.down) // -3.0
(-3.001).rounded(.down) // -4.0
(-3.999).rounded(.down) // -4.0
.toNearestOrAwayFromZero
等价于C的整数函数。
3.000.rounded(.toNearestOrAwayFromZero) // 3.0
3.001.rounded(.toNearestOrAwayFromZero) // 3.0
3.499.rounded(.toNearestOrAwayFromZero) // 3.0
3.500.rounded(.toNearestOrAwayFromZero) // 4.0
3.999.rounded(.toNearestOrAwayFromZero) // 4.0
(-3.000).rounded(.toNearestOrAwayFromZero) // -3.0
(-3.001).rounded(.toNearestOrAwayFromZero) // -3.0
(-3.499).rounded(.toNearestOrAwayFromZero) // -3.0
(-3.500).rounded(.toNearestOrAwayFromZero) // -4.0
(-3.999).rounded(.toNearestOrAwayFromZero) // -4.0
这个舍入规则也可以使用零参数的round()方法访问。
3.000.rounded() // 3.0
// ...
(-3.000).rounded() // -3.0
// ...
.toNearestOrEven
四舍五入到最接近的允许值;如果两个值相等接近,则选择偶数;相当于C的rint(/非常类似于nearbyint)函数。
3.499.rounded(.toNearestOrEven) // 3.0
3.500.rounded(.toNearestOrEven) // 4.0 (up to even)
3.501.rounded(.toNearestOrEven) // 4.0
4.499.rounded(.toNearestOrEven) // 4.0
4.500.rounded(.toNearestOrEven) // 4.0 (down to even)
4.501.rounded(.toNearestOrEven) // 5.0 (up to nearest)
.towardZero
相当于C语言的trunc函数。
3.000.rounded(.towardZero) // 3.0
3.001.rounded(.towardZero) // 3.0
3.999.rounded(.towardZero) // 3.0
(-3.000).rounded(.towardZero) // 3.0
(-3.001).rounded(.towardZero) // 3.0
(-3.999).rounded(.towardZero) // 3.0
如果舍入的目的是准备处理整数(例如,舍入后通过FloatPoint初始化使用Int),我们可以简单地利用这样一个事实,即在使用Double(或Float等)初始化Int时,小数部分将被截断。
Int(3.000) // 3
Int(3.001) // 3
Int(3.999) // 3
Int(-3.000) // -3
Int(-3.001) // -3
Int(-3.999) // -3
.up
等价于C细胞函数。
3.000.rounded(.up) // 3.0
3.001.rounded(.up) // 4.0
3.999.rounded(.up) // 4.0
(-3.000).rounded(.up) // 3.0
(-3.001).rounded(.up) // 3.0
(-3.999).rounded(.up) // 3.0
附录:访问FloatingPoint的源代码,以验证C函数与不同的FloatingPointRoundingRule规则的等价性
如果我们愿意,我们可以查看FloatingPoint协议的源代码,直接看到C函数等价于公共FloatingPointRoundingRule规则。
从斯威夫特/ stdlib /公共/核心/ FloatingPoint.swift。Gyb我们看到,舍入(_:)方法的默认实现使我们得到了变化的舍入(_:)方法:
public func rounded(_ rule: FloatingPointRoundingRule) -> Self {
Var LHS = self
lhs.round(规则)
返回lh
}
从斯威夫特/ stdlib /公共/核心/ FloatingPointTypes.swift。我们发现round(_:)的默认实现,其中FloatingPointRoundingRule规则和C的四舍五入函数之间的等价性是显而易见的:
public mutating func round(_ rule: FloatingPointRoundingRule) {
switch rule {
case .toNearestOrAwayFromZero:
_value = Builtin.int_round_FPIEEE${bits}(_value)
case .toNearestOrEven:
_value = Builtin.int_rint_FPIEEE${bits}(_value)
case .towardZero:
_value = Builtin.int_trunc_FPIEEE${bits}(_value)
case .awayFromZero:
if sign == .minus {
_value = Builtin.int_floor_FPIEEE${bits}(_value)
}
else {
_value = Builtin.int_ceil_FPIEEE${bits}(_value)
}
case .up:
_value = Builtin.int_ceil_FPIEEE${bits}(_value)
case .down:
_value = Builtin.int_floor_FPIEEE${bits}(_value)
}
}