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()к сожалению, не доступны на детской площадке