Swift 3 & 4 - 利用FloatingPoint
协议中蓝图化的rounded(_:)
方法
FloatingPoint
协议(例如Double
和Float
符合该协议)蓝图化了rounded(_:)
方法
func rounded(_ rule: FloatingPointRoundingRule) -> Self
其中 FloatingPointRoundingRule
是一个枚举,列举了许多不同的舍入规则:
case awayFromZero
四舍五入到最接近的允许值,其大小大于或等于源值。
case down
向下舍入到最接近的允许值,小于或等于源值。
case toNearestOrAwayFromZero
四舍五入到最接近的允许值;如果两个值同样接近,则选择具有更大大小的值。
case toNearestOrEven
四舍五入到最接近的允许值;如果两个值同样接近,则选择偶数。
case towardZero
向最接近的允许值舍入,其大小小于或等于源值。
case up
向上舍入到最接近的允许值,大于或等于源值。
We make use of similar examples to the ones from
@Suragch's excellent answer to show these different rounding options in practice.
.awayFromZero
四舍五入到最接近的允许值,其大小大于或等于源值; 在C函数中没有直接相当的选项,因为这使用了条件性的ceil
或floor
,对于正数和负数的self
,分别使用。
3.000.rounded(.awayFromZero)
3.001.rounded(.awayFromZero)
3.999.rounded(.awayFromZero)
(-3.000).rounded(.awayFromZero)
(-3.001).rounded(.awayFromZero)
(-3.999).rounded(.awayFromZero)
.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.001.rounded(.toNearestOrAwayFromZero)
3.499.rounded(.toNearestOrAwayFromZero)
3.500.rounded(.toNearestOrAwayFromZero)
3.999.rounded(.toNearestOrAwayFromZero)
(-3.000).rounded(.toNearestOrAwayFromZero)
(-3.001).rounded(.toNearestOrAwayFromZero)
(-3.499).rounded(.toNearestOrAwayFromZero)
(-3.500).rounded(.toNearestOrAwayFromZero)
(-3.999).rounded(.toNearestOrAwayFromZero)
这个取整规则也可以通过零参数
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
通过
Double
(或
Float
等)初始化),我们可以简单地利用这样一个事实:当使用
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 语言中的 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
协议的源代码,直接查看C函数相当于公共FloatingPointRoundingRule
规则。
从swift/stdlib/public/core/FloatingPoint.swift.gyb中可以看出,rounded(_:)
方法的默认实现使用可变的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()
不可用。 - MrBrpow()
函数定义在Darwin库中,因此您需要首先import Darwin
(或import Foundation
或import Cocoa
或import UIKit
,它们都会在内部导入Darwin)。 - Mike Slround()
,它返回一个整数类型。 - Martin Rround()
”函数在小数点后面的数字 >= 0.5 时向上舍入,< 0.5 时向下舍入(标准四舍五入)。但是有例外,“round(-16.5)
”返回的结果是-17而不是-16。这是一个错误吗? - Daniel T.