iOS-精度数据处理NSDecimalNumber

2021-04-09  本文已影响0人  XTK_iOS

作用

double num1 = 6.67;
double num2 = 15.666666;
NSLog(@"%f",num1*num2);//结果:104.496662,不精确
NSDecimalNumber *price = [NSDecimalNumber decimalNumberWithString:@"6.67"];
NSDecimalNumber *totalPrice = [NSDecimalNumber decimalNumberWithString:@"15.666666"];
NSDecimalNumber *amount = [totalPrice decimalNumberByMultiplyingBy:price];
NSLog(@"%@",amount);//结果104.49666222

用法

加减乘除以及乘方
NSDecimalNumber *price = [NSDecimalNumber decimalNumberWithString:@"6.67"];
NSDecimalNumber *totalPrice = [NSDecimalNumber decimalNumberWithString:@"15.666666"];
NSDecimalNumber *amount = [totalPrice decimalNumberByAdding:price];
NSLog(@"%@",amount);//22.336666
NSDecimalNumber *price = [NSDecimalNumber decimalNumberWithString:@"6.67"];
NSDecimalNumber *totalPrice = [NSDecimalNumber decimalNumberWithString:@"15.666666"];
NSDecimalNumber *amount = [totalPrice decimalNumberBySubtracting:price];
NSLog(@"%@",amount);//8.996666000000001
NSDecimalNumber *price = [[NSDecimalNumber alloc] initWithDouble:6.67];
NSDecimalNumber *totalPrice = [[NSDecimalNumber alloc] initWithDouble:15.666666];
NSDecimalNumber *amount = [totalPrice decimalNumberByMultiplyingBy:price];
NSLog(@"%@",amount);//104.49666222
NSDecimalNumber *price = [[NSDecimalNumber alloc] initWithDouble:6.67];
NSDecimalNumber *totalPrice = [[NSDecimalNumber alloc] initWithDouble:15.666666];
NSDecimalNumber *amount = [totalPrice decimalNumberByDividingBy:price];
NSLog(@"%@",amount);//2.348825487256372
NSDecimalNumber *totalPrice = [[NSDecimalNumber alloc] initWithDouble:2];
NSDecimalNumber *amount = [totalPrice decimalNumberByRaisingToPower:2];
NSLog(@"%@",amount); //4

数值处理

NSDecimalNumber的公共协议处理类,可以设置舍入模式以及计算错误的处理;配合NSDecimalNumber来使用.
    /// 数值处理
    /// @param roundingMode 规则 NSRoundPlain :四舍五入  NSRoundDown :向下取舍   NSRoundUp:向上取舍  Bankers :特殊四舍五入 
    /// @param scale  精确到几位小数
    /// @param raiseOnExactness  精度错误处理;YES:如果出现错误,将引发异常,NO:忽略错误并将控制权放回给调用者。
    /// @param raiseOnOverflow  溢出错误处理;YES:如果出现错误,将引发异常,NO:忽略错误并将控制权放回给调用者。
    /// @param raiseOnUnderflow  下溢错误处理;YES:如果出现错误,将引发异常,NO:忽略错误并将控制权放回给调用者。
    /// @param raiseOnDivideByZero  除以0的错误处理;YES:如果出现错误,将引发异常,NO:忽略错误并将控制权放回给调用者。
    /**
     Bankers :特殊四舍五入
     value      1.2   1.21  1.25  1.35  1.27
     Bankers    1.2   1.2   1.2   1.4   1.3
    */
    
    NSDecimalNumberHandler *roundingBehavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundDown scale:3 raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO];
NSDecimalNumber *roundedOunces = [amount decimalNumberByRoundingAccordingToBehavior:roundingBehavior];
NSLog(@"%@",roundedOunces); //2.348
简单使用
//加
- (NSString *)add:(NSString *)string {
    NSDecimalNumber *number1 = [NSString getDecimalNumberWithString:self];
    NSDecimalNumber *number2 = [NSString getDecimalNumberWithString:string];
    return [[number1 decimalNumberByAdding:number2] stringValue];
}
//减
- (NSString *)subtract:(NSString *)string {
    NSDecimalNumber *number1 = [NSString getDecimalNumberWithString:self];
    NSDecimalNumber *number2 = [NSString getDecimalNumberWithString:string];
    return [[number1 decimalNumberBySubtracting:number2] stringValue];
}
//乘
- (NSString *)multiply:(NSString *)string {
    NSDecimalNumber *number1 = [NSString getDecimalNumberWithString:self];
    NSDecimalNumber *number2 = [NSString getDecimalNumberWithString:string];
    return [[number1 decimalNumberByMultiplyingBy:number2] stringValue];
}
//除
- (NSString *)divide:(NSString *)string {
    NSDecimalNumber *number1 = [NSString getDecimalNumberWithString:self];
    NSDecimalNumber *number2 = [NSString getDecimalNumberWithString:string];
    return [[number1 decimalNumberByDividingBy:number2] stringValue];
}

+ (NSDecimalNumber *)getDecimalNumberWithString:(NSString *)string {
    if (IsString(string) && fabs([string doubleValue]) > 0) {
        return [NSDecimalNumber decimalNumberWithString:string];
    }else {
        return [NSDecimalNumber decimalNumberWithString:@"0"];
    }
}

/**
 * 取舍运算
 * @param number 要取舍的数
 * @param roundModel 规则 
 * @param scale  位数
 * @param keep 是否填充0
 */
+ (NSString *)decimalNumber:(NSString *)number RoundingMode:(NSRoundingMode)roundModel scale:(short)scale isKeep:(BOOL)keep {
    
    if (number == nil) {
        return @"--";
    }
    
    // 负数需要反过来
    if ([number doubleValue] < 0) {
        if (roundModel == NSRoundDown) {
            roundModel = NSRoundUp;
        }else {
            roundModel = NSRoundDown;
        }
    }
    
    if (scale < 0) {
        scale += 1;
    }
    NSDecimalNumber *decimalNum = [NSDecimalNumber decimalNumberWithString:number];
    NSDecimalNumberHandler *roundingBehavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:roundModel scale:scale raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO];
    NSDecimalNumber *roundedNumber = [decimalNum decimalNumberByRoundingAccordingToBehavior:roundingBehavior];
    if (scale > 0) {
        if (keep == YES) {
            NSString *scaleString = [NSString stringWithFormat:@"%%.%df",scale];
            return [NSString stringWithFormat:scaleString, roundedNumber.doubleValue];
        }else {
            return [NSString stringWithFormat:@"%@",roundedNumber];
        }
    }else {
        return [NSString stringWithFormat:@"%lld",roundedNumber.longLongValue];
    }
}
上一篇下一篇

猜你喜欢

热点阅读