问题描述
我们在开发中当涉及到金额或者对数字有特殊要求时,一般会有下面三种情况。
1.对数字进行四舍五入;
2.只保留几位,后面的都不要;
3.只保留几位,后面的不管是多少,都进位。
解决方案
其实从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);
接下来就一一讲解代码中出现的方法:
这边我们采用倒叙的方法来解释会比较好理解:
首先:
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协议,就得去看NSDecimalNumberHandler的说明。
NSDecimalNumberHandler *roundUp = [NSDecimalNumberHandler
decimalNumberHandlerWithRoundingMode:NSRoundPlain
scale:2
raiseOnExactness:NO
raiseOnOverflow:NO
raiseOnUnderflow:NO
raiseOnDivideByZero:YES];
这句话中的6个参数分别表示:
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:超过的位数都舍弃
NSRoundUp:超过的位数向前进1
NSRoundBankers:
Round to the closest possible return value; when halfway between two possibilities, return the possibility whose last digit is even.
官方文档中的说法,这也是四舍五入,不同的是,如果结果可能在两者之间的话,会返回偶数值。
下图可以清楚地看出NSRoundingMode每种类型的返回值:
2.scale:就是保留几位小数
3.raiseOnExactness:如果设置为YES,当精确度发生错误的时候会抛出异常,否则就直接返回NAN
4.raiseOnOverflow:如果设置为YES,当发生溢出时会抛出异常,否则就直接返回NAN
5.raiseOnUnderflow:如果设置为YES,当发生下溢时会抛出异常,否则就直接返回NAN
6.raiseOnDivideByZero:如果设置为YES,当除以0时会抛出异常,否则就直接返回NAN
一般我们3,4,5这几个都会选择NO,毕竟平时开发发生上述错误的可能性不高,除以0的设置为YES,防止出现误操作。
关于保留小数就讲这么多啦,以上是做项目时遇到的问题,查找文档后得出的结论,如有错误,欢迎指正批评:)