objective c - Redondeo NSDecimalNumber
objective-c cocoa (4)
Estoy usando esta solución:
import Foundation
extension NSDecimalNumber {
public func round(_ decimals:Int) -> NSDecimalNumber {
return self.rounding(accordingToBehavior:
NSDecimalNumberHandler(roundingMode: .plain,
scale: Int16(decimals),
raiseOnExactness: false,
raiseOnOverflow: false,
raiseOnUnderflow: false,
raiseOnDivideByZero: false))
}
}
let amount = NSDecimalNumber(string: "123.456")
amount.round(2) --> 123.46
amount.round(1) --> 123.5
amount.round(0) --> 123
amount.round(-1) --> 120
amount.round(-2) --> 100
Me está costando mucho descubrir algo que parece que debería ser muy simple. Necesito redondear con precisión un NSDecimalNumber a un número particular de lugares decimales (determinado en tiempo de ejecución). Por lo que puedo decir, tengo dos opciones, ninguna de las cuales me gusta.
- Conviértase en un flotador y use las funciones de redondeo en C: No me gusta esto porque la precisión importa en este caso. Los flotadores no siempre pueden representar con precisión los números decimales, y esto podría causar problemas.
- Conviértalo en una cadena usando NSNumberFormatter y luego vuelva a convertir: no me gusta este porque me parece feo e ineficiente.
¿Hay alguna otra forma que me haya perdido? Tiene que haber una manera fácil de redondear los Números Decimales de NS, pero parece que no puedo entender por mi vida lo que es.
Lo tengo funcionando usando el siguiente código en Swift 3.
let amount = NSDecimalNumber(string: "123.456789")
let handler = NSDecimalNumberHandler(roundingMode: .plain, scale: 2, raiseOnExactness: false, raiseOnOverflow: false, raiseOnUnderflow: false, raiseOnDivideByZero: false)
let roundedAmount = amount.rounding(accordingToBehavior: handler)
Tenga en cuenta el parámetro de escala, que se utiliza para definir los lugares decimales que necesita. Se describe aquí: https://developer.apple.com/reference/foundation/nsdecimalnumberhandler/1578295-decimalnumberhandlerwithrounding
Para aquellos que prefieren código de ejemplo ...
Para redondear a 2 lugares decimales (12345.68):
NSDecimalNumber *originalNumber = [NSDecimalNumber decimalNumberWithString:@"12345.6789"];
NSDecimalNumberHandler *behavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain
scale:2
raiseOnExactness:NO
raiseOnOverflow:NO
raiseOnUnderflow:NO
raiseOnDivideByZero:NO];
NSDecimalNumber *roundedNumber = [originalNumber decimalNumberByRoundingAccordingToBehavior:behavior];
Para redondear al millar más cercano (12000):
NSDecimalNumber *originalNumber = [NSDecimalNumber decimalNumberWithString:@"12345.6789"];
NSDecimalNumberHandler *behavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain
scale:-3
raiseOnExactness:NO
raiseOnOverflow:NO
raiseOnUnderflow:NO
raiseOnDivideByZero:NO];
NSDecimalNumber *roundedNumber = [originalNumber decimalNumberByRoundingAccordingToBehavior:behavior];
Simplemente llame a decimalNumberByRoundingAccordingToBehavior:
con el protocolo NSDecimalNumberBehaviors
deseado. Consulte la referencia NSDecimalNumberBehaviors
en los documentos dev .
Actualización: consulte http://www.cimgf.com/2008/04/23/cocoa-tutorial-dont-be-lazy-with-nsdecimalnumber-like-me/