iOS基本计算之NSDecimalNumber

float 浮点型计算会出现精度丢失问题
写了一个基本OC的计算类解决问题
临时用,很多地方可以修改或者改进

NSDecimalNumber
继承自NSNumber,苹果针对浮点类型计算精度问题提供出来的计算类,基于十进制的科学计数法来计算,同时可以指定舍入模式,一般用于货币计算。

.h文件

//
//  CPCalculate.h
//  CooperTest
//
//  Created by jhf on 2019/2/12.
//  Copyright © 2019年 jhf. All rights reserved.
//

#import <Foundation/Foundation.h>

@class CPCalculate;

typedef CPCalculate *(^CPCalculateBlock)(id num);

NS_ASSUME_NONNULL_BEGIN

@interface CPCalculate : NSObject

+ (CPCalculate *)initWithOriginNum:(id)num;

@property (nonatomic, strong) NSDecimalNumber *originNum;

@property (nonatomic, copy) CPCalculateBlock add;

@property (nonatomic, copy) CPCalculateBlock subtract;

@property (nonatomic, copy) CPCalculateBlock multiply;

@property (nonatomic, copy) CPCalculateBlock divide;

@end

NS_ASSUME_NONNULL_END

.m文件

//
//  CPCalculate.m
//  CooperTest
//
//  Created by jhf on 2019/2/12.
//  Copyright © 2019年 jhf. All rights reserved.
//

#import "CPCalculate.h"

@implementation CPCalculate

+ (CPCalculate *)initWithOriginNum:(id)num; {
    NSDecimalNumber *number = [[self class] checkNumber:num];
    if (!number) {
       number = [[NSDecimalNumber alloc] initWithString:@"0"];
    }
    return [[[self class] alloc] initWithOriginNum:number];
}

- (instancetype)initWithOriginNum:(NSDecimalNumber *)num;
{
    self = [super init];
    if (self) {
         _originNum = num;
        [self setupBlock];
    }
    return self;
}


/**
 设置block 调用
 */
- (void)setupBlock {
    MJWeakSelf;
    self.add = ^CPCalculate *(id num) {
        [weakSelf add:num];
        return weakSelf;
    };
    self.subtract = ^CPCalculate *(id num) {
        [weakSelf subtract:num];
        return weakSelf;
    };
    self.multiply = ^CPCalculate *(id num) {
        [weakSelf multiply:num];
        return weakSelf;
    };
    self.divide = ^CPCalculate *(id num) {
        [weakSelf divide:num];
        return weakSelf;
    };
}

/**
 加
 
 @param num 加数
 @return self
 */
- (CPCalculate *)add:(id)num; {
    NSDecimalNumber *number = [[self class] checkNumber:num];
    if (number) {
        self.originNum = [self.originNum decimalNumberByAdding:number];
    }
    return self;
}

/**
 减

 @param num 减数
 @return self
 */
- (CPCalculate *)subtract:(id)num; {
    NSDecimalNumber *number = [[self class] checkNumber:num];
    if (number) {
        self.originNum = [self.originNum decimalNumberBySubtracting:number];
    }
    return self;
}

/**
 乘

 @param num 乘数
 @return self
 */
- (CPCalculate *)multiply:(id)num; {
    NSDecimalNumber *number = [[self class] checkNumber:num];
    if (number) {
        self.originNum = [self.originNum decimalNumberByMultiplyingBy:number];
    }
    return self;
}

/**
 除

 @param num 除数
 @return self
 */
- (CPCalculate *)divide:(id)num; {
    NSDecimalNumber *number = [[self class] checkNumber:num];
    if (number) {
        if ([[self class] aDecimalNumberWithStringOrNumberOrDecimalNumber:num compareAnotherDecimalNumberWithStringOrNumberOrDecimalNumber:@(0)] == 0) {
            NSLog(@"除数不可为零");
        } else {
            self.originNum = [self.originNum decimalNumberByDividingBy:number];
        }
    }
    return self;
}

/**
 检查数字是否符合条件

 @param number 数
 @return NSDecimalNumber
 */
+ (NSDecimalNumber *)checkNumber:(id)number {
    if ([number isKindOfClass:[NSString class]]) {
        return [NSDecimalNumber decimalNumberWithString:number];
    } else if([number isKindOfClass:[NSDecimalNumber class]]) {
        return number;
    } else if ([number isKindOfClass:[NSNumber class]]) {
        return [NSDecimalNumber decimalNumberWithDecimal:[number decimalValue]];
    } else{
        NSLog(@"输入正确的类型");
        return nil;
    }
}


/**
 两个数的比较

 @param num1 第一个数
 @param num2 第二个数
 @return 比较结果
 */
+ (NSComparisonResult)aDecimalNumberWithStringOrNumberOrDecimalNumber:(id)num1 compareAnotherDecimalNumberWithStringOrNumberOrDecimalNumber:(id)num2 {
    NSDecimalNumber *number1 = [CPCalculate checkNumber:num1];
    NSDecimalNumber *number2 = [CPCalculate checkNumber:num2];
    if (!(number1 && number2)) {
        return false;
    }
    return [number1 compare:number2];
}

@end

测试使用

	NSString *num1 = @"1.99999999999";
    NSString *num2 = @"0.00000000001";
    NSString *num3 = @"0.00000000002";
    NSString *num4 = @"0.00000000003";
    NSString *num5 = @"0.00000000004";
    CPCalculate *cp = [CPCalculate initWithOriginNum:num1];
    NSLog(@"%g", cp.add(num2).subtract(num3).multiply(num4).divide(num5).originNum.doubleValue);

结果 1.5

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值