objective-c cocoa rounding

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.

  1. 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.
  2. 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];