問題描述
我們在開發(fā)中當(dāng)涉及到金額或者對數(shù)字有特殊要求時,一般會有下面三種情況。
1.對數(shù)字進(jìn)行四舍五入;
2.只保留幾位,后面的都不要;
3.只保留幾位,后面的不管是多少,都進(jìn)位。
解決方案
其實(shí)從iOS 2.0之后蘋果就出了一套解決方案了,那就是NSDecimalNumber。
接下來我們就要看如何使用了:
CGFloat money = 0.123456789;
NSDecimalNumberHandler *roundUp = [NSDecimalNumberHandler
decimalNumberHandlerWithRoundingMode:NSRoundPlain
scale:2
raiseOnExactness:NO
raiseOnOverflow:NO
raiseOnUnderflow:NO
raiseOnDivideByZero:YES];
NSDecimalNumber *tempNumber = [[NSDecimalNumber alloc] initWithDouble:money];
NSDecimalNumber *dividend = [NSDecimalNumber decimalNumberWithString:@"2"];
NSDecimalNumber *result = [tempNumber decimalNumberByDividingBy:dividend withBehavior:roundUp];
NSLog(@"%@", result);
接下來就一一講解代碼中出現(xiàn)的方法:
這邊我們采用倒敘的方法來解釋會比較好理解:
首先:
NSDecimalNumber *result = [tempNumber decimalNumberByDividingBy:dividend withBehavior:roundUp];
這句話的意思就是返回一個NSDecimalNumber,這個NSDecimalNumber是tempNumber除以dividend并且采取了一定行為的,那么這個Behavior到底是什么,又能有哪些行為呢,接下來就要看NSDecimalNumberHandler。
For an example of a class that adopts the NSDecimalBehaviors protocol, see the specification for NSDecimalNumberHandler.
這是蘋果官方文檔中的一句話,意思大致就是,你想要用采用NSDecimalBehaviors協(xié)議,就得去看NSDecimalNumberHandler的說明。
NSDecimalNumberHandler *roundUp = [NSDecimalNumberHandler
decimalNumberHandlerWithRoundingMode:NSRoundPlain
scale:2
raiseOnExactness:NO
raiseOnOverflow:NO
raiseOnUnderflow:NO
raiseOnDivideByZero:YES];
這句話中的6個參數(shù)分別表示:
1.RoundingMode:
typedef NS_ENUM(NSUInteger, NSRoundingMode) {
NSRoundPlain, // Round up on a tie
NSRoundDown, // Always down == truncate
NSRoundUp, // Always up
NSRoundBankers // on a tie round so last digit is even
};
NSRoundPlain:四舍五入
NSRoundDown:超過的位數(shù)都舍棄
NSRoundUp:超過的位數(shù)向前進(jìn)1
NSRoundBankers:
Round to the closest possible return value; when halfway between two possibilities, return the possibility whose last digit is even.
官方文檔中的說法,這也是四舍五入,不同的是,如果結(jié)果可能在兩者之間的話,會返回偶數(shù)值。
下圖可以清楚地看出NSRoundingMode每種類型的返回值:

2.scale:就是保留幾位小數(shù)
3.raiseOnExactness:如果設(shè)置為YES,當(dāng)精確度發(fā)生錯誤的時候會拋出異常,否則就直接返回NAN
4.raiseOnOverflow:如果設(shè)置為YES,當(dāng)發(fā)生溢出時會拋出異常,否則就直接返回NAN
5.raiseOnUnderflow:如果設(shè)置為YES,當(dāng)發(fā)生下溢時會拋出異常,否則就直接返回NAN
6.raiseOnDivideByZero:如果設(shè)置為YES,當(dāng)除以0時會拋出異常,否則就直接返回NAN
一般我們3,4,5這幾個都會選擇NO,畢竟平時開發(fā)發(fā)生上述錯誤的可能性不高,除以0的設(shè)置為YES,防止出現(xiàn)誤操作。
關(guān)于保留小數(shù)就講這么多啦,以上是做項(xiàng)目時遇到的問題,查找文檔后得出的結(jié)論,如有錯誤,歡迎指正批評:)