Swift 3和4-使用协议中设计的rounded(_:)
方法FloatingPoint
的FloatingPoint
协议(到其例如Double
与Float
符合)蓝图rounded(_:)
方法
func rounded(_ rule: FloatingPointRoundingRule) -> Self
FloatingPointRoundingRule
枚举在哪里枚举许多不同的舍入规则:
case awayFromZero
四舍五入到其幅度大于或等于源的幅度的最接近的允许值。
case down
四舍五入为小于或等于源的最接近的允许值。
case toNearestOrAwayFromZero
四舍五入到最接近的允许值;如果两个值相等,则选择一个较大的值。
case toNearestOrEven
四舍五入到最接近的允许值;如果两个值相等接近,则选择偶数。
case towardZero
四舍五入到其大小小于或等于源的大小的最接近的允许值。
case up
舍入到大于或等于源的最接近的允许值。
我们使用与@Suragch出色答案中的示例相似的示例,以实际展示这些不同的舍入选项。
.awayFromZero
四舍五入到大于或等于源的最大允许值;因此,C函数之间没有直接等价的关系,分别使用self
,ceil
或的符号分别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 floor
函数。
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 round
函数。
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
也可以使用零参数rounded()
方法访问此舍入规则。
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
如果舍入的目的是准备使用整数(例如,舍入后Int
通过FloatPoint
初始化使用),则我们可以简单地利用以下事实:在初始化Int
使用Double
(或Float
等)时,小数部分将被舍去。
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 ceil
函数。
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
协议的源代码,以直接查看与公共FloatingPointRoundingRule
规则等效的C函数。
从swift / stdlib / public / core / FloatingPoint.swift.gyb中,我们看到该方法的默认实现rounded(_:)
使我们有了mutating round(_:)
方法:
public func rounded(_ rule: FloatingPointRoundingRule) -> Self {
var lhs = self
lhs.round(rule)
return lhs
}
从swift / stdlib / public / core / FloatingPointTypes.swift.gyb中,我们找到的默认实现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)
}
}
pow()
不幸的是没有在操场上