Swift 3 y 4: haciendo uso del rounded(_:)método como se muestra en el FloatingPointprotocolo
El FloatingPointprotocolo (al cual, por ejemplo, Doubley se Floatajusta) esboza el rounded(_:)método
func rounded(_ rule: FloatingPointRoundingRule) -> Self
¿Dónde FloatingPointRoundingRulehay una enumeración que enumera una serie de reglas de redondeo diferentes:
case awayFromZero
Redondee al valor permitido más cercano cuya magnitud sea mayor o igual que la de la fuente.
case down
Redondea al valor permitido más cercano que sea menor o igual que la fuente.
case toNearestOrAwayFromZero
Redondear al valor permitido más cercano; Si dos valores son igualmente cercanos, se elige el de mayor magnitud.
case toNearestOrEven
Redondear al valor permitido más cercano; Si dos valores son igualmente cercanos, se elige el par.
case towardZero
Redondee al valor permitido más cercano cuya magnitud sea menor o igual que la de la fuente.
case up
Redondea al valor permitido más cercano que sea mayor o igual que la fuente.
Utilizamos ejemplos similares a los de la excelente respuesta de @ Suragch para mostrar estas diferentes opciones de redondeo en la práctica.
.awayFromZero
Redondee al valor permitido más cercano cuya magnitud sea mayor o igual que la de la fuente; no hay equivalente directo entre las funciones de C, ya que esto utiliza, condicionalmente en el signo de self, ceilo floor, para valores positivos y negativos de self, respectivamente.
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
Equivalente a la floorfunción 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
Equivalente a la roundfunción 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
También se puede acceder a esta regla de redondeo utilizando el rounded()método de argumento cero .
3.000.rounded() // 3.0
// ...
(-3.000).rounded() // -3.0
// ...
.toNearestOrEven
Redondear al valor permitido más cercano; si dos valores son igualmente cercanos, se elige el par; equivalente a la función C rint(/ muy similar a 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
Equivalente a la truncfunción 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
Si el propósito del redondeo es prepararse para trabajar con un número entero (por ejemplo, usando Intpor FloatPointinicialización después del redondeo), podríamos simplemente hacer uso del hecho de que al inicializar un Intuso de a Double(o Floatetc.), la parte decimal se truncará.
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
Equivalente a la ceilfunción 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
Anexo: visitando el código fuente para FloatingPointverificar la equivalencia de las funciones C con los diferentesFloatingPointRoundingRule reglas
Si quisiéramos, podemos echar un vistazo al código fuente del FloatingPointprotocolo para ver directamente los equivalentes de la función C al públicoFloatingPointRoundingRule reglas .
Desde swift / stdlib / public / core / FloatingPoint.swift.gyb , vemos que la implementación predeterminada del rounded(_:)método nos convierte en el round(_:)método de mutación :
public func rounded(_ rule: FloatingPointRoundingRule) -> Self {
var lhs = self
lhs.round(rule)
return lhs
}
En swift / stdlib / public / core / FloatingPointTypes.swift.gyb encontramos la implementación predeterminada de round(_:), en la que la equivalencia entre las FloatingPointRoundingRulereglas y las funciones de redondeo en C es evidente:
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()desafortunadamente no está disponible en un patio de juegos