resumen libro latino fahrenheit español bradbury audiolibro analisis swift int double rounding

swift - libro - ¿Cómo redondear un doble al int más cercano a la vez?



fahrenheit 451 ray bradbury (6)

Estoy tratando de hacer una calculadora de la tasa de crecimiento ( Double ) que redondeará el resultado al entero más cercano y volverá a calcular a partir de allí, como tal:

let firstUsers = 10.0 let growth = 0.1 var users = firstUsers var week = 0 while users < 14 { println("week /(week) has /(users) users") users += users * growth week += 1 }

pero no he podido hasta ahora.

EDITAR Yo lo hice así:

var firstUsers = 10.0 let growth = 0.1 var users:Int = Int(firstUsers) var week = 0 while users <= 14 { println("week /(week) has /(users) users") firstUsers += firstUsers * growth users = Int(firstUsers) week += 1 }

Aunque no me importa que siempre esté redondeando, no me gusta porque los firstUsers tenían que convertirse en una variable y cambiar a lo largo del programa (para hacer el siguiente cálculo), lo que no quiero que suceda. .


Swift 3: haciendo uso del método rounded(_:) tal como se imprimió en el protocolo FloatingPoint

El protocolo FloatingPoint (al cual, por ejemplo, Double y Float ajusta) dibuja el rounded()

func rounded(_ rule: FloatingPointRoundingRule) -> Self

Donde FloatingPointRoundingRule es una enumeración que enumera una serie de reglas de redondeo diferentes:

case awayFromZero

Redondea al valor permitido más cercano cuya magnitud sea mayor o igual a la de la fuente.

case down

Redondea al valor permitido más cercano que sea menor o igual que la fuente.

case toNearestOrAwayFromZero

Redondea al valor permitido más cercano; si dos valores son igualmente cercanos, se elige el de mayor magnitud.

case toNearestOrEven

Redondea al valor permitido más cercano; si dos valores son igualmente cercanos, se elige el par.

case towardZero

Redondea al valor permitido más cercano cuya magnitud sea menor o igual a la de la fuente.

case up

Redondea al valor permitido más cercano que sea mayor o igual que la fuente.

Hacemos uso de 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 a la de la fuente; no existe un equivalente directo entre las funciones C, ya que esto utiliza, condicionalmente, el signo de self , ceil o 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 función de 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

Equivalente a la función 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

También se puede acceder a esta regla de redondeo utilizando el método zero argument rounded() .

3.000.rounded() // 3.0 // ... (-3.000).rounded() // -3.0 // ...

.toNearestOrEven

Redondea 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) // 4.0

.towardZero

Equivalente a la función 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

Si el propósito del redondeo es prepararse para trabajar con un número entero (por ejemplo, usando Int por inicialización de FloatPoint después del redondeo), podríamos simplemente utilizar el hecho de que al inicializar un Int usando un Double (o Float etc.), la parte decimal será truncado.

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 función 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

Adición: visitar el código fuente de FloatingPoint para verificar la equivalencia de las funciones C a las diferentes reglas de FloatingPointRoundingRule

Si queremos, podemos echar un vistazo al código fuente del protocolo FloatingPoint para ver directamente las funciones C equivalentes a las reglas públicas de FloatingPointRoundingRule .

Desde swift/stdlib/public/core/FloatingPoint.swift.gyb vemos que la implementación predeterminada del método rounded(_:) nos hace del método de la round(_:) mutación round(_:) :

public func rounded(_ rule: FloatingPointRoundingRule) -> Self { var lhs = self lhs.round(rule) return lhs }

Desde swift/stdlib/public/core/FloatingPointTypes.swift.gyb encontramos la implementación predeterminada de round(_:) , en la cual la equivalencia entre las reglas de FloatingPointRoundingRule 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) } }


Hay una round disponible en la biblioteca de la Foundation (en realidad está en Darwin , pero la Foundation importa Darwin y la mayoría de las veces querrás usar Foundation lugar de usar Darwin directamente) .

import Foundation users = round(users)

Ejecutando su código en un patio de recreo y luego llamando:

print(round(users))

Productos:

15.0

round() siempre redondea cuando el lugar decimal es >= .5 y hacia abajo cuando es < .5 (redondeo estándar). Puede usar floor() para forzar el redondeo hacia abajo y ceil() para forzar el redondeo hacia arriba.

Si necesita redondear a un lugar específico, entonces multiplica por pow(10.0, number of places) , round , y luego divide por pow(10, number of places) :

Ronda a 2 decimales:

let numberOfPlaces = 2.0 let multiplier = pow(10.0, numberOfPlaces) let num = 10.12345 let rounded = round(10.12345 * multiplier) / multiplier print(rounded)

Productos:

10.12

Nota: Debido a la forma en que funciona la matemática de coma flotante, rounded puede no ser siempre perfecta. Lo mejor es pensar más en una aproximación de redondeo. Si está haciendo esto para fines de visualización, es mejor usar el formato de cadenas para formatear el número en lugar de usar las matemáticas para redondearlo.


Para redondear un doble al entero más cercano, solo usa round() .

var x = 3.7 x.round() // x = 4.0

Si no desea modificar el valor original, utilice rounded() :

let x = 3.7 let y = x.rounded() // y = 4.0. x = 3.7

Como uno podría esperar ( o no ), un número como 3.5 se redondea hacia arriba y un número como -3.5 se redondea hacia abajo. Si necesita un comportamiento de redondeo diferente, puede usar una de las reglas de redondeo . Por ejemplo:

var x = 3.7 x.round(.towardZero) // 3.0

Si necesita una Int real, simplemente conviértala en una:

let myInt = Int(myDouble.rounded())

Notas

  • Esta respuesta está completamente reescrita. Mi respuesta anterior se refería a las funciones matemáticas C, como round , lround , floor y ceil . Sin embargo, ahora que Swift tiene esta funcionalidad incorporada, ya no puedo recomendar el uso de esas funciones. Gracias a @dfri por señalarme esto. Vea la excelente respuesta de @dfri aquí . También hice algo similar para redondear un CGFloat .

Swift 3

var myNum = 8.09

myNum.rounded () // result = 8 que se almacena en myNum


Swift 3: si desea redondear a un cierto número de dígitos, por ejemplo, 5.678434 -> 5.68, puede simplemente combinar la función round () o roundf () con una multiplicación:

let value:Float = 5.678434 let roundedValue = roundf(value * 100) / 100 print(roundedValue) //5.68


También puede extender FloatingPoint en Swift 3 de la siguiente manera:

extension FloatingPoint { func rounded(to n: Int) -> Self { return (self / Self(n)).rounded() * Self(n) } } 324.0.rounded(to: 5) // 325