ios swift double nstimeinterval

ios - Redondeando un valor doble a x número de decimales en swift



double nstimeinterval (27)

¿Cómo redondeo esto a, digamos, 1.543 cuando imprimo totalWorkTimeInHours ?

Para redondear totalWorkTimeInHours a 3 dígitos para imprimir, use el constructor de String que toma una cadena de format :

print(String(format: "%.3f", totalWorkTimeInHours))

¿Alguien puede decirme cómo redondear un valor doble a x número de decimales en Swift?

Yo tengo:

var totalWorkTimeInHours = (totalWorkTime/60/60)

Con totalWorkTime siendo un NSTimeInterval (doble) en segundo.

totalWorkTimeInHours me dará las horas, pero me da la cantidad de tiempo en un número tan largo y preciso, por ejemplo, 1.543240952039 ......

¿Cómo redondeo esto a, digamos, 1.543 cuando imprimo totalWorkTimeInHours ?


Extensión para Swift 2

Una solución más general es la siguiente extensión, que funciona con Swift 2 y iOS 9:

extension Double { /// Rounds the double to decimal places value func roundToPlaces(places:Int) -> Double { let divisor = pow(10.0, Double(places)) return round(self * divisor) / divisor } }


Extensión para Swift 3

En Swift 3, la round se reemplaza por rounded :

extension Double { /// Rounds the double to decimal places value func rounded(toPlaces places:Int) -> Double { let divisor = pow(10.0, Double(places)) return (self * divisor).rounded() / divisor } }


Ejemplo que devuelve Doble redondeado a 4 decimales:

let x = Double(0.123456789).roundToPlaces(4) // x becomes 0.1235 under Swift 2 let x = Double(0.123456789).rounded(toPlaces: 4) // Swift 3 version


Aquí hay uno para SwiftUI si necesita un elemento de texto con el valor numérico.

struct RoundedDigitText : View { let digits : Int let number : Double var body : some View { Text(String(format: "%./(digits)f", number)) } }


Basándose en la respuesta de Yogi, aquí hay una función Swift que hace el trabajo:

func roundToPlaces(value:Double, places:Int) -> Double { let divisor = pow(10.0, Double(places)) return round(value * divisor) / divisor }


Con Swift 5, según sus necesidades, puede elegir uno de los 9 estilos siguientes para obtener un resultado redondeado de un Double .

# 1 Usando el método FloatingPoint rounded()

En el caso más simple, puede usar el método Double round() .

let roundedValue1 = (0.6844 * 1000).rounded() / 1000 let roundedValue2 = (0.6849 * 1000).rounded() / 1000 print(roundedValue1) // returns 0.684 print(roundedValue2) // returns 0.685

# 2 Uso del método rounded(_:) FloatingPoint rounded(_:)

let roundedValue1 = (0.6844 * 1000).rounded(.toNearestOrEven) / 1000 let roundedValue2 = (0.6849 * 1000).rounded(.toNearestOrEven) / 1000 print(roundedValue1) // returns 0.684 print(roundedValue2) // returns 0.685

# 3 Usando la función round Darwin

Foundation ofrece una función round través de Darwin.

import Foundation let roundedValue1 = round(0.6844 * 1000) / 1000 let roundedValue2 = round(0.6849 * 1000) / 1000 print(roundedValue1) // returns 0.684 print(roundedValue2) // returns 0.685

# 4. Usando un método personalizado de Double extensión creado con las funciones de pow y pow

Si desea repetir la operación anterior muchas veces, refactorizar su código puede ser una buena idea.

import Foundation extension Double { func roundToDecimal(_ fractionDigits: Int) -> Double { let multiplier = pow(10, Double(fractionDigits)) return Darwin.round(self * multiplier) / multiplier } } let roundedValue1 = 0.6844.roundToDecimal(3) let roundedValue2 = 0.6849.roundToDecimal(3) print(roundedValue1) // returns 0.684 print(roundedValue2) // returns 0.685

# 5. Uso del NSDecimalNumber rounding(accordingToBehavior:) NSDecimalNumber rounding(accordingToBehavior:) método rounding(accordingToBehavior:)

Si es necesario, NSDecimalNumber ofrece una solución detallada pero poderosa para redondear números decimales.

import Foundation let scale: Int16 = 3 let behavior = NSDecimalNumberHandler(roundingMode: .plain, scale: scale, raiseOnExactness: false, raiseOnOverflow: false, raiseOnUnderflow: false, raiseOnDivideByZero: true) let roundedValue1 = NSDecimalNumber(value: 0.6844).rounding(accordingToBehavior: behavior) let roundedValue2 = NSDecimalNumber(value: 0.6849).rounding(accordingToBehavior: behavior) print(roundedValue1) // returns 0.684 print(roundedValue2) // returns 0.685

# 6. Uso de la función NSDecimalRound(_:_:_:_:)

import Foundation let scale = 3 var value1 = Decimal(0.6844) var value2 = Decimal(0.6849) var roundedValue1 = Decimal() var roundedValue2 = Decimal() NSDecimalRound(&roundedValue1, &value1, scale, NSDecimalNumber.RoundingMode.plain) NSDecimalRound(&roundedValue2, &value2, scale, NSDecimalNumber.RoundingMode.plain) print(roundedValue1) // returns 0.684 print(roundedValue2) // returns 0.685

# 7. Usando NSString init(format:arguments:) inicializador

Si desea devolver un NSString de su operación de redondeo, usar el inicializador NSString es una solución simple pero eficiente.

import Foundation let roundedValue1 = NSString(format: "%.3f", 0.6844) let roundedValue2 = NSString(format: "%.3f", 0.6849) print(roundedValue1) // prints 0.684 print(roundedValue2) // prints 0.685

# 8. Usando String init(format:_:) inicializador

El tipo de String de Swift se NSString clase NSString de NSString . Por lo tanto, puede usar el siguiente código para devolver una String de su operación de redondeo:

import Foundation let roundedValue1 = String(format: "%.3f", 0.6844) let roundedValue2 = String(format: "%.3f", 0.6849) print(roundedValue1) // prints 0.684 print(roundedValue2) // prints 0.685

# 9. Usando NumberFormatter

Si espera obtener una String? desde su operación de redondeo, NumberFormatter ofrece una solución altamente personalizable.

import Foundation let formatter = NumberFormatter() formatter.numberStyle = NumberFormatter.Style.decimal formatter.roundingMode = NumberFormatter.RoundingMode.halfUp formatter.maximumFractionDigits = 3 let roundedValue1 = formatter.string(from: 0.6844) let roundedValue2 = formatter.string(from: 0.6849) print(String(describing: roundedValue1)) // prints Optional("0.684") print(String(describing: roundedValue2)) // prints Optional("0.685")


El código para dígitos específicos después de decimales es:

var a = 1.543240952039 var roundedString = String(format: "%.3f", a)

Aquí, el% .3f le dice a Swift que redondee este número a 3 decimales. Y si desea un número doble, puede usar este código:

// String to Double

var roundedString = Double(String(format: "%.3f", b))


Encontré esto preguntándome si es posible corregir la entrada de un usuario. Es decir, si ingresan tres decimales en lugar de dos por un monto en dólares. Digamos 1.111 en lugar de 1.11, ¿puedes arreglarlo redondeando? ¡La respuesta por muchas razones es no! Con dinero por encima de 0.001 eventualmente causaría problemas en una chequera real.

Aquí hay una función para verificar la entrada de los usuarios para demasiados valores después del período. Pero lo que permitirá 1., 1.1 y 1.11.

Se supone que el valor ya se ha verificado para una conversión exitosa de una Cadena a una Doble.

//find the distance between two points let coordinateSource = CLLocation(latitude: 30.7717625, longitude:76.5741449 ) let coordinateDestination = CLLocation(latitude: 29.9810859, longitude: 76.5663599) let distanceInMeters = coordinateSource.distance(from: coordinateDestination) let valueInKms = distanceInMeters/1000 let preciseValueUptoThreeDigit = Double(round(1000*valueInKms)/1000) self.lblTotalDistance.text = "Distance is : /(preciseValueUptoThreeDigit) kms"


Esta es una especie de solución temporal larga, que puede ser útil si sus necesidades son un poco más complejas. Puede usar un formateador de números en Swift.

let numberFormatter: NSNumberFormatter = { let nf = NSNumberFormatter() nf.numberStyle = .DecimalStyle nf.minimumFractionDigits = 0 nf.maximumFractionDigits = 1 return nf }()

Suponga que su variable que desea imprimir es

var printVar = 3.567

Esto asegurará que se devuelva en el formato deseado:

numberFormatter.StringFromNumber(printVar)

El resultado aquí será "3.6" (redondeado). Si bien esta no es la solución más económica, la doy porque el OP mencionó la impresión (en cuyo caso, una Cadena no es indeseable), y porque esta clase permite establecer múltiples parámetros.


Este es un algoritmo más flexible de redondeo a N dígitos significativos

Solución Swift 3

extension Double { // Rounds the double to ''places'' significant digits func roundTo(places:Int) -> Double { guard self != 0.0 else { return 0 } let divisor = pow(10.0, Double(places) - ceil(log10(fabs(self)))) return (self * divisor).rounded() / divisor } } // Double(0.123456789).roundTo(places: 2) = 0.12 // Double(1.23456789).roundTo(places: 2) = 1.2 // Double(1234.56789).roundTo(places: 2) = 1200


Este es un código completamente trabajado

Swift 3.0 / 4.0, Xcode 9.0 GM / 9.2

let doubleValue : Double = 123.32565254455 self.lblValue.text = String(format:"%.f", doubleValue) print(self.lblValue.text)

salida - 123

self.lblValue_1.text = String(format:"%.1f", doubleValue) print(self.lblValue_1.text)

salida - 123.3

self.lblValue_2.text = String(format:"%.2f", doubleValue) print(self.lblValue_2.text)

salida - 123.33

self.lblValue_3.text = String(format:"%.3f", doubleValue) print(self.lblValue_3.text)

salida - 123.326


Esto parece funcionar en Swift 5.

Bastante sorprendido ya no hay una función estándar para esto.

// Truncamiento de dobles a n-decimales con redondeo

extension Double { var clean: String { return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(format: "%.2f", self) } }


La mejor manera de formatear una propiedad doble es utilizar los métodos predefinidos de Apple.

mutating func round(_ rule: FloatingPointRoundingRule)

FloatingPointRoundingRule es una enumeración que tiene las siguientes posibilidades

Casos de enumeración:

case awayFromZero Redondea al valor permitido más cercano cuya magnitud es mayor o igual que la de la fuente.

caso abajo Redondear al valor permitido más cercano que sea menor o igual que la fuente.

case toNearestOrAwayFromZero Round al valor permitido más cercano; Si dos valores son igualmente cercanos, se elige el de mayor magnitud.

case toNearestOrEven Round al valor permitido más cercano; Si dos valores son igualmente cercanos, se elige el par.

caso hacia cero Redondea al valor permitido más cercano cuya magnitud es menor o igual que la de la fuente.

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

var aNumber : Double = 5.2 aNumber.rounded(.up) // 6.0


No Swift, pero estoy seguro de que tienes la idea.

var x = 1.5657676754 var y = (x*10).rounded()/10 print(y) // 1.6


Para evitar imperfecciones de flotación, use Decimal

extension Float { func rounded(rule: NSDecimalNumber.RoundingMode, scale: Int) -> Float { var result: Decimal = 0 var decimalSelf = NSNumber(value: self).decimalValue NSDecimalRound(&result, &decimalSelf, scale, rule) return (result as NSNumber).floatValue } }

ex.
1075.58 se redondea a 1075.57 cuando se usa Float con escala: 2 y .down
1075.58 se redondea a 1075.58 cuando se usa Decimal con escala: 2 y .down


Puede usar la función round de Swift para lograr esto.

Para redondear un Double con precisión de 3 dígitos, primero multiplíquelo por 1000, redondee y divida el resultado redondeado por 1000:

let x = 1.23556789 let y = Double(round(1000*x)/1000) print(y) // 1.236

Además de cualquier tipo de soluciones printf(...) o String(format: ...) , el resultado de esta operación sigue siendo del tipo Double .

EDITAR:
En cuanto a los comentarios de que a veces no funciona, lea esto:

Lo que todo informático debe saber sobre la aritmética de coma flotante


Puedes agregar esta extensión:

let ex: Double = 10.123546789 print(ex.clean) // 10.12

y llámalo así:

//func need to be where transactionAmount.text is in scope func checkDoublesForOnlyTwoDecimalsOrLess()->Bool{ var theTransactionCharacterMinusThree: Character = "A" var theTransactionCharacterMinusTwo: Character = "A" var theTransactionCharacterMinusOne: Character = "A" var result = false var periodCharacter:Character = "." var myCopyString = transactionAmount.text! if myCopyString.containsString(".") { if( myCopyString.characters.count >= 3){ theTransactionCharacterMinusThree = myCopyString[myCopyString.endIndex.advancedBy(-3)] } if( myCopyString.characters.count >= 2){ theTransactionCharacterMinusTwo = myCopyString[myCopyString.endIndex.advancedBy(-2)] } if( myCopyString.characters.count > 1){ theTransactionCharacterMinusOne = myCopyString[myCopyString.endIndex.advancedBy(-1)] } if theTransactionCharacterMinusThree == periodCharacter { result = true } if theTransactionCharacterMinusTwo == periodCharacter { result = true } if theTransactionCharacterMinusOne == periodCharacter { result = true } }else { //if there is no period and it is a valid double it is good result = true } return result }


Si desea redondear valores Double , es posible que desee utilizar Swift Decimal para no introducir ningún error que pueda surgir cuando intente matemática con estos valores redondeados. Si usa Decimal , puede representar con precisión los valores decimales de ese valor de punto flotante redondeado.

Entonces puedes hacer:

pow10np = pow(10,num_places); val = round(val*pow10np) / pow10np;

Luego, puede obtener el valor Decimal redondeado de la siguiente manera:

var x = 1.5657676754 var y = (x*10000).rounded()/10000 print(y) // 1.5658

Y si desea mostrarlo con un número específico de lugares decimales (así como localizar la cadena para la configuración regional actual del usuario), puede usar un NumberFormatter :

var x = 1.5657676754 var y = (x*100).rounded()/100 print(y) // 1.57


Una manera práctica puede ser el uso de la extensión de tipo Doble

extension Double { var roundTo2f: Double {return Double(round(100 *self)/100) } var roundTo3f: Double {return Double(round(1000*self)/1000) } }

Uso:

let regularPie: Double = 3.14159 var smallerPie: Double = regularPie.roundTo3f // results 3.142 var smallestPie: Double = regularPie.roundTo2f // results 3.14


Ya sea:

  1. Usando String(format:) :

    • Typecast Double to String con el especificador de formato %.3f y luego nuevamente a Double

      Double(String(format: "%.3f", 10.123546789))!

    • O extienda Double para manejar lugares N-Decimales:

      extension Double { func rounded(toDecimalPlaces n: Int) -> Double { return Double(String(format: "%./(n)f", self))! } }

  2. Por cálculo

    • multiplica con 10 ^ 3, redondea y luego divide por 10 ^ 3 ...

      (1000 * 10.123546789).rounded()/1000

    • O extienda Double para manejar lugares N-Decimales:

      extension Double { func rounded(toDecimalPlaces n: Int) -> Double { let multiplier = pow(10, Double(n)) return (multiplier * self).rounded()/multiplier } }


yo usaría

print(String(format: "%.3f", totalWorkTimeInHours))

y cambie .3f a cualquier número de números decimales que necesite


En Swift 2.0 y Xcode 7.2:

let pi: Double = 3.14159265358979 String(format:"%.2f", pi)

Ejemplo:


En Swift 3.0 y Xcode 8.0:

yourLabel.text = String(format:"%.2f", yourDecimalValue)

Use esta extensión así,

extension Double { func roundTo(places: Int) -> Double { let divisor = pow(10.0, Double(places)) return (self * divisor).rounded() / divisor } }


Swift 4, Xcode 10

let doubleValue = 3.567 let roundedValue = doubleValue.roundTo(places: 2) print(roundedValue) // prints 3.56


Utilice la biblioteca integrada de Foundation Darwin

SWIFT 3

extension Double { func round(to places: Int) -> Double { let divisor = pow(10.0, Double(places)) return Darwin.round(self * divisor) / divisor } }

Uso:

let number:Double = 12.987654321 print(number.round(to: 3))

Salidas: 12.988


redondea un valor doble a x número de decimales
NO. de dígitos después del decimal

extension Double { /// Convert `Double` to `Decimal`, rounding it to `scale` decimal places. /// /// - Parameters: /// - scale: How many decimal places to round to. Defaults to `0`. /// - mode: The preferred rounding mode. Defaults to `.plain`. /// - Returns: The rounded `Decimal` value. func roundedDecimal(to scale: Int = 0, mode: NSDecimalNumber.RoundingMode = .plain) -> Decimal { var decimalValue = Decimal(self) var result = Decimal() NSDecimalRound(&result, &decimalValue, scale, mode) return result } }

let foo = 427.3000000002 let value = foo.roundedDecimal(to: 2) // results in 427.30

let formatter = NumberFormatter() formatter.maximumFractionDigits = 2 formatter.minimumFractionDigits = 2 if let string = formatter.string(for: value) { print(string) }


extension String{ var roundedValue:String { return String(format: "%.3f", self) }}


totalWorkTimeInHours.roundedValue

Uso:

extension Double { func truncate(to places: Int) -> Double { return Double(Int((pow(10, Double(places)) * self).rounded())) / pow(10, Double(places)) } }