Redondear un valor doble a x número de decimales en Swift

Resuelto Leighton asked hace 9 años • 36 respuestas

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

Tengo:

var totalWorkTimeInHours = (totalWorkTime/60/60)

Con totalWorkTimeser un NSTimeInterval (doble) en segundo.

totalWorkTimeInHoursme 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?

Leighton avatar Dec 07 '14 08:12 Leighton
Aceptado

Puede utilizar roundla función de Swift para lograr esto.

Para redondear a Doublecon precisión de 3 dígitos, primero multiplíquelo por 1000, redondeelo y divida el resultado redondeado entre 1000:

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

A diferencia de cualquier tipo printf(...)de String(format: ...)solución, el resultado de esta operación sigue siendo de tipo Double.

Respecto a los comentarios de que a veces no funciona, lea esto: Lo que todo programador debe saber sobre la aritmética de punto flotante

zisoft avatar Dec 07 '2014 08:12 zisoft

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 roundse 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
Sebastian avatar Sep 15 '2015 08:09 Sebastian

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

Para redondear totalWorkTimeInHoursa 3 dígitos para imprimir, use el Stringconstructor que toma una formatcadena:

print(String(format: "%.3f", totalWorkTimeInHours))
vacawama avatar Dec 07 '2014 03:12 vacawama

Con Swift 5, según tus necesidades, puedes elegir uno de los 9 estilos siguientes para tener un resultado redondeado a partir de un archivo Double.


#1. Usando FloatingPoint rounded()el método

En el caso más sencillo, puedes utilizar el Double rounded()método.

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. Usando FloatingPoint rounded(_:)el método

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 roundla función de Darwin

Fundación ofrece una roundfunción a 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 Doublemétodo personalizado de extensión creado con Darwin roundy powfunciones

Si deseas repetir la operación anterior muchas veces, refactorizar tu 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. Usando NSDecimalNumber rounding(accordingToBehavior:)el método

Si es necesario, NSDecimalNumberofrece una solución detallada pero potente 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. Usando NSDecimalRound(_:_:_:_:)la función

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 a NSStringde su operación de redondeo, usar NSStringel inicializador 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 Swift Stringestá unido a la clase de Foundation NSString. Por lo tanto, puede utilizar el siguiente código para devolver un valor Stringde 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. UsandoNumberFormatter

Si espera obtener un beneficio String?de su operación de redondeo, NumberFormatterle ofrecemos 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")
Imanou Petit avatar Jun 26 '2016 09:06 Imanou Petit