NSDecimalNumber

NSDecimalNumber : NSNumber

创建

    NSDecimal decimal;
    NSDecimalNumber *decimalNumber = [NSDecimalNumber decimalNumberWithDecimal:decimal];
    NSDecimalNumber *decimalNumber1 = [NSDecimalNumber decimalNumberWithMantissa:12345 exponent:-4 isNegative:YES];
    NSDecimalNumber *decimalNumber2 = [NSDecimalNumber decimalNumberWithString:@"-1.2345"];
    NSDecimalNumber *decimalNumber3 = [NSDecimalNumber decimalNumberWithString:@"-1.2345" locale:nil];
    // 对应的 实例化初始化,略;
    
    // 默认值
    NSLog(@"zero:%@", [NSDecimalNumber zero]);
    NSLog(@"one:%@", [NSDecimalNumber one]);
    NSLog(@"minimumDecimalNumber:%@", [NSDecimalNumber minimumDecimalNumber]);
    NSLog(@"maximumDecimalNumber:%@", [NSDecimalNumber maximumDecimalNumber]);
    NSLog(@"notANumber:%@", [NSDecimalNumber notANumber]);

计算

  • decimalNumberA + decimalNumberB
    decimalNumber = [decimalNumber1 decimalNumberByAdding:decimalNumber2];
    NSLog(@"add:%@",decimalNumber);
    
    // 指定代理,舍入模式选择
    decimalNumber = [decimalNumber1 decimalNumberByAdding:decimalNumber2 withBehavior:self];
    NSLog(@"add 2:%@",decimalNumber1);
  • decimalNumberA - decimalNumberB
    decimalNumber = [decimalNumber1 decimalNumberBySubtracting:decimalNumber2];
    decimalNumber = [decimalNumber1 decimalNumberBySubtracting:decimalNumber2 withBehavior:self];
  • decimalNumberA * decimalNumberB
    decimalNumber = [decimalNumber1 decimalNumberByMultiplyingBy:decimalNumber2];
    decimalNumber = [decimalNumber1 decimalNumberByMultiplyingBy:decimalNumber2 withBehavior:self];    
  • decimalNumberA / decimalNumberB
    decimalNumber = [decimalNumber1 decimalNumberByDividingBy:decimalNumber2];
    decimalNumber = [decimalNumber1 decimalNumberByMultiplyingBy:decimalNumber2 withBehavior:self];
  • decimalNumberA ^ uintB
    decimalNumber = [decimalNumber1 decimalNumberByRaisingToPower:2];
    decimalNumber = [decimalNumber1 decimalNumberByRaisingToPower:2 withBehavior:self];
  • decimalNumberA * 10 ^ shortB
    decimalNumber = [decimalNumber1 decimalNumberByMultiplyingByPowerOf10:2];
    decimalNumber = [decimalNumber1 decimalNumberByMultiplyingByPowerOf10:2 withBehavior:self];

舍入方式

  • 自身舍入
    decimalNumber = [decimalNumber decimalNumberByRoundingAccordingToBehavior:self];
  • 计算舍入
    decimalNumber = [decimalNumber1 decimalNumberByAdding:decimalNumber2 withBehavior:self];

舍入处理

代理 NSDecimalNumberBehaviors

{
    decimalNumber = [decimalNumber decimalNumberByRoundingAccordingToBehavior:self];
}

#pragma mark - NSDecimalNumberBehaviors

// 舍入方式
- (NSRoundingMode)roundingMode {
    return NSRoundBankers;
}

// 保留小数位数
- (short)scale {
    return 2;
}

// 舍入结果异常处理:
- (nullable NSDecimalNumber *)exceptionDuringOperation:(SEL)operation error:(NSCalculationError)error leftOperand:(NSDecimalNumber *)leftOperand rightOperand:(nullable NSDecimalNumber *)rightOperand {
    NSLog(@"leftOperand:%@", leftOperand);
    NSLog(@"rightOperand:%@", rightOperand);
    switch (error) {
        case NSCalculationNoError: {
            return rightOperand;
        }
            break;
        case NSCalculationLossOfPrecision:{
            return rightOperand;
        }
            break;
        case NSCalculationUnderflow:{
            return [NSDecimalNumber minimumDecimalNumber];
        }
            break;
        case NSCalculationOverflow:{
            return [NSDecimalNumber maximumDecimalNumber];
        }
            break;
        case NSCalculationDivideByZero:{
            return [NSDecimalNumber notANumber];
        }
            break;
    }
}

系统提供默认

    //[NSDecimalNumber defaultBehavior]
    decimalNumber = [decimalNumber decimalNumberByRoundingAccordingToBehavior:[NSDecimalNumber defaultBehavior]];

    //[NSDecimalNumberHandler defaultDecimalNumberHandler]
    decimalNumber = [decimalNumber decimalNumberByRoundingAccordingToBehavior:[NSDecimalNumberHandler defaultDecimalNumberHandler]];

系统提供代理类 NSDecimalNumberHandler 处理

    NSDecimalNumberHandler *handler = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundBankers scale:2 raiseOnExactness:YES raiseOnOverflow:YES raiseOnUnderflow:YES raiseOnDivideByZero:YES];
    decimalNumber = [decimalNumber decimalNumberByRoundingAccordingToBehavior:handler];

注:使用代理类处理时 NSException 指定的几个参数为 YES 时,错误时会抛出异常,需要自己处理

// 我们使用,除以 0 来做示例
    @try {
        decimalNumber = [decimalNumber decimalNumberByDividingBy:[NSDecimalNumber zero] withBehavior:handler];

    }
    @catch (NSException *exception) {
        if ([exception.name isEqualToString:NSDecimalNumberDivideByZeroException]) {
            NSLog(@"除数为 0!");
        }
    }
    @finally {
        // 结果处理
        decimalNumber = [NSDecimalNumber decimalNumberWithString:@"999"];
    }
    NSLog(@"%@",[decimalNumber descriptionWithLocale:nil]);

数据转换

    NSDecimal decimalValue = decimalNumber1.decimalValue;
    double doubleValue = decimalNumber1.doubleValue;
    NSString *decimalString = [decimalNumber1 descriptionWithLocale:nil];
    const char *decimalChar = decimalNumber1.objCType;

比较

    NSComparisonResult *res = [num1 compare:num2];

异常常量

FOUNDATION_EXPORT NSExceptionName const NSDecimalNumberExactnessException;    // 丢失精度
FOUNDATION_EXPORT NSExceptionName const NSDecimalNumberOverflowException;     // 向上溢出
FOUNDATION_EXPORT NSExceptionName const NSDecimalNumberUnderflowException;    // 向下溢出
FOUNDATION_EXPORT NSExceptionName const NSDecimalNumberDivideByZeroException; // 除数为 0