iOS NSDecimalNumber 基本使用

NSDecimalNumber 主要应用于需要高精度处理的数据,基本使用方法如下:

1.加减乘除计算

- (NSDecimalNumber *)decimalNumberByAdding:(NSDecimalNumber *)decimalNumber;
- (NSDecimalNumber *)decimalNumberBySubtracting:(NSDecimalNumber *)decimalNumber;
- (NSDecimalNumber *)decimalNumberByMultiplyingBy:(NSDecimalNumber *)decimalNumber;
- (NSDecimalNumber *)decimalNumberByDividingBy:(NSDecimalNumber *)decimalNumber;

2.四舍五入 NSRoundingMode

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
};

3.数值大小比较

- (NSComparisonResult)compare:(NSNumber *)decimalNumber;

NSComparisonResult 结果

typedef NS_CLOSED_ENUM(NSInteger, NSComparisonResult) {
    NSOrderedAscending = -1L,
    NSOrderedSame,
    NSOrderedDescending
};

4.NSDecimalNumberHandler 类 用于做一些基本的设置,包括容错的设置,如下:

 NSDecimalNumberHandler* roundingBehavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundDown scale:position raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO];

5.对于代码中未做错误处理的补救方法

NSDecimalNumber 关于加减乘除的方法都可以包含一个 NSDecimalNumberBehaviors 参数,

 - (NSDecimalNumber *)decimalNumberByRoundingAccordingToBehavior:(nullable id )behavior;

如果代码中都未做设置,也可以通过继承协议,重写 exceptionDuringOperation 方法达到同样的目的,以下只是做了除数为0的异常处理

-(NSRoundingMode)roundingMode
{
    return NSRoundDown;
}
-(short)scale
{
    return NSDecimalNoScale;
}
-(NSDecimalNumber*)exceptionDuringOperation:(SEL)operation error:(NSCalculationError)error leftOperand:(NSDecimalNumber *)leftOperand rightOperand:(NSDecimalNumber *)rightOperand
{
    if (error == NSCalculationDivideByZero) {
        return [NSDecimalNumber zero];
    }
    return nil;
}

另外也可以通过 Method swizzled 达到同样的目的,使所有不包含 NSDecimalNumberBehaviors 的方法都被替换掉,遵循统一设置

+(void)load
{
    [super load];
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
 
        Class class_NSDecimalNumber = NSClassFromString(@"NSDecimalNumber");
        Method original_NSDecimalNumber = class_getInstanceMethod(class_NSDecimalNumber, @selector(decimalNumberByDividingBy:));
        
        Method swizzled_NSDecimalNumber = class_getInstanceMethod(class_NSDecimalNumber, @selector(my_decimalNumberByDividingBy:));
        method_exchangeImplementations(original_NSDecimalNumber, swizzled_NSDecimalNumber);
    });
}

-(NSDecimalNumber*)my_decimalNumberByDividingBy:(NSDecimalNumber*)number
{
    return [(NSDecimalNumber*)self decimalNumberByDividingBy:number withBehavior:self];
}

你可能感兴趣的:(iOS NSDecimalNumber 基本使用)