金融类app各种数值的精确计算问题

关于数值的计算就是按照字符串直接转doubleValue的方式转化为后进行加减乘除运算。这样做在大多数情况下是不会有问题的,但如果经过全面测试的话,有些字符串转double会出现精度损失问题,计算结果也会出现不准确的问题.

NSDecimalNumber是苹果提供的专门金融货币精确数值计算的API。

+ (instancetype)decimalNumberHandlerWithRoundingMode:(NSRoundingMode)roundingMode
                                               scale:(short)scale
                                    raiseOnExactness:(BOOL)raiseOnExactness
                                     raiseOnOverflow:(BOOL)raiseOnOverflow
                                    raiseOnUnderflow:(BOOL)raiseOnUnderflow
                                 raiseOnDivideByZero:(BOOL)raiseOnDivideByZero
参数 说明
roundingMode 要使用的舍入模式,有四种值: NSRoundUp, NSRoundDown, NSRoundPlain, and NSRoundBankers
scale 结果保留几位小数
raiseOnExactness 发生精确错误时是否抛出异常,一般为NO
raiseOnOverflow 发生溢出错误时是否抛出异常,一般为NO
raiseOnUnderflow 发生不足错误时是否抛出异常,一般为NO
raiseOnDivideByZero 被0除时是否抛出异常,一般为YES

RoundingMode 舍入模式 官方注释
// Rounding policies :
// Original
// value 1.2 1.21 1.25 1.35 1.27
// Plain 1.2 1.2 1.3 1.4 1.3
// Down 1.2 1.2 1.2 1.3 1.2
// Up 1.2 1.3 1.3 1.4 1.3
// Bankers 1.2 1.2 1.2 1.4 1.3

参数 说明
NSRoundPlain // Round up on a tie, 标准四舍五入模式
NSRoundDown // Always down == truncate 截断所有超出部分
NSRoundUp // Always up, 进一法
NSRoundBankers // on a tie round so last digit is even 特殊的四舍五入.最后一位是5的情况下,如果前一位是偶数则舍弃,前一位是奇数则进一位

NSDecimalNumber是进行数值计算的对象,ji所有的加减乘除,幂运算操作对象。

    NSDecimalNumberHandler *handler = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundBankers
                                                                                             scale:2
                                                                                  raiseOnExactness:NO
                                                                                   raiseOnOverflow:NO
                                                                                  raiseOnUnderflow:NO
                                                                               raiseOnDivideByZero:YES];
    NSDecimalNumber *num1           = [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:@"%@",@"2.37"]];
    NSDecimalNumber *num2           = [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:@"%@",@"15.89"]];

    //加
    NSDecimalNumber *addResult      = [num1 decimalNumberByAdding:num2
                                                     withBehavior:handler];
    //减
    NSDecimalNumber *subtractResult = [num1 decimalNumberBySubtracting:num2
                                                          withBehavior:handler];
    //乘
    NSDecimalNumber *multiplyResult = [num1 decimalNumberByMultiplyingBy:num2
                                                            withBehavior:handler];
    //除
    NSDecimalNumber *divideResult   = [num1 decimalNumberByDividingBy:num2
                                                       withBehavior:handler];
    //平方
    NSDecimalNumber *powerResult    = [num1 decimalNumberByRaisingToPower:2
                                                          withBehavior:handler];
    NSLog(@"\n%f\n%f\n%f\n%f\n%f",[addResult doubleValue],[subtractResult doubleValue],[multiplyResult doubleValue],[divideResult doubleValue],[powerResult doubleValue]);

计算结果仅用于显示作用,计算必须使用原数值进行计算,结果使用公式转换进行显示。

你可能感兴趣的:(金融类app各种数值的精确计算问题)