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
Эквивалент floor
функции 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
Эквивалент round
функции 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
Это округление правило также можно получить с помощью нулевого аргумента 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
Эквивалент trunc
функции C.
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
Эквивалент ceil
функции 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
правилам.
Из 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()
к сожалению, не доступны на детской площадке