2010-10-20 52 views
20

我最難找出一件看起來應該很簡單的東西。我需要精確地將NSDecimalNumber舍入到特定的小數位數(在運行時確定)。據我所知,我有兩個選項,我都不喜歡。Rounding NSDecimalNumber

  1. 轉換爲浮動,並用C取整函數:我不喜歡這一點,因爲在這種情況下,精度非常重要的。花車並不總是準確地表示十進制數字,這可能會導致問題。
  2. 使用NSNumberFormatter轉換爲字符串,然後轉換回來:我不喜歡這一個,因爲它看起來很醜並且效率低下。

有沒有另一種方法,我錯過了?有得到是一個簡單的方法來完成NSDecimalNumbers舍入,但我似乎無法弄清楚我的生活是什麼。

回答

32

您只需撥打decimalNumberByRoundingAccordingToBehavior:與所需的NSDecimalNumberBehaviors協議。請參閱dev docs中的NSDecimalNumberBehaviors參考。

更新:見http://www.cimgf.com/2008/04/23/cocoa-tutorial-dont-be-lazy-with-nsdecimalnumber-like-me/

+0

這就是門票!謝謝! – 2010-10-23 15:59:14

+0

優秀的鏈接:-) – 2012-06-11 13:03:58

+0

RTFM不是響應。響應是「您只需調用decimalNumberByRoundingAccordingToBehavior:使用所需的NSDecimalNumberBehaviors協議。」 dev文檔被引用來提供各種協議的枚舉,而不是在這裏複製它們。 – CuriousRabbit 2013-10-14 16:06:07

17

對於那些寧願示例代碼...

四捨五入到小數點後2位(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]; 

舍入到最近的千(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]; 
3

我知道它在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) 

請注意scale參數,用於定義您需要的小數位數。這裏概述:https://developer.apple.com/reference/foundation/nsdecimalnumberhandler/1578295-decimalnumberhandlerwithrounding

0

我使用此解決方案:

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