iOS-小数点后面显示N个9

案例一:

    NSString *jsonStr = @"{\"9.70\":\"9.70\", \"97.40\":97.40, \"80.40\":80.40, \"188.40\":188.40}";
    NSLog(@"json:%@", jsonStr);
    NSData *jsonData_ = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
    NSError *jsonParsingError_ = nil;
    NSDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:[NSJSONSerialization JSONObjectWithData:jsonData_ options:0 error:&jsonParsingError_]];
    NSLog(@"dic:%@", dic);
    
    NSLog(@"9.70-%@",dic[@"9.70"]);
    NSLog(@"97.40-%@",dic[@"97.40"]);
    NSLog(@"80.40-%@",dic[@"80.40"]);
    NSLog(@"188.40-%@",dic[@"188.40"]);

    NSLog(@"9.70-%@",decimalNumberWithDouble([dic[@"9.70"] doubleValue]));
    NSLog(@"97.40-%@",decimalNumberWithDouble([dic[@"97.40"] doubleValue]));
    NSLog(@"80.40-%@",decimalNumberWithDouble([dic[@"80.40"] doubleValue]));
    NSLog(@"188.40-%@",decimalNumberWithDouble([dic[@"188.40"] doubleValue]));

打印结果

2021-01-20 14:41:50.010048+0800 OCTest[3177:186113] json:{"9.70":"9.70", "97.40":97.40, "80.40":80.40, "188.40":188.40}
2021-01-20 14:41:50.010452+0800 OCTest[3177:186113] dic:{
    "188.40" = "188.4";
    "80.40" = "80.40000000000001";
    "9.70" = "9.70";
    "97.40" = "97.40000000000001";
}
2021-01-20 14:41:50.010684+0800 OCTest[3177:186113] 9.70-9.70
2021-01-20 14:41:50.010929+0800 OCTest[3177:186113] 97.40-97.40000000000001
2021-01-20 14:41:50.011200+0800 OCTest[3177:186113] 80.40-80.40000000000001
2021-01-20 14:41:50.011461+0800 OCTest[3177:186113] 188.40-188.4
2021-01-20 14:41:50.011737+0800 OCTest[3177:186113] 9.70-9.7
2021-01-20 14:41:50.011957+0800 OCTest[3177:186113] 97.40-97.4
2021-01-20 14:41:50.012233+0800 OCTest[3177:186113] 80.40-80.4
2021-01-20 14:41:50.012516+0800 OCTest[3177:186113] 188.40-188.4

结论:

1.不管什么类型、先转成double然后执行下面代码可解决精度缺失的问题。

NSString *decimalNumberWithDouble(double conversionValue) {
    // lf 默认显示6位小数、根据第7位四舍五入
    NSString *doubleString = [NSString stringWithFormat:@"%lf", conversionValue];
    NSDecimalNumber *decNumber = [NSDecimalNumber decimalNumberWithString:doubleString];
    return [decNumber stringValue];
}

2.如果json里面是string类型,前端直接用string,可显示出9.70类似格式的样式,并且不会出现精度缺失的问题。

案例二:

模型

.h

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface Num : NSObject

#pragma mark - 对应的后台数据为string
@property (nonatomic, assign) double num1;
@property (nonatomic, assign) double num2;
@property (nonatomic, assign) double num3;
@property (nonatomic, copy) NSString *num4;
@property (nonatomic, copy) NSString *num5;
@property (nonatomic, copy) NSString *num6;
@property (nonatomic, strong) NSNumber *num7;
@property (nonatomic, strong) NSNumber *num8;
@property (nonatomic, strong) NSNumber *num9;

#pragma mark - 对应的后台数据为double
@property (nonatomic, assign) double num10;
@property (nonatomic, assign) double num11;
@property (nonatomic, assign) double num12;
@property (nonatomic, copy) NSString *num13;
@property (nonatomic, copy) NSString *num14;
@property (nonatomic, copy) NSString *num15;
@property (nonatomic, strong) NSNumber *num16;
@property (nonatomic, strong) NSNumber *num17;
@property (nonatomic, strong) NSNumber *num18;
@end

NS_ASSUME_NONNULL_END

.m
#import "Num.h"

@implementation Num

@end

测试代码

- (void)test {
    
    NSString *jsonString = @"{\"data\":{\"num1\":\"9.70\",\"num2\":\"80.40\",\"num3\":\"97.40\",\"num4\":\"9.70\",\"num5\":\"80.40\",\"num6\":\"97.40\",\"num7\":\"9.70\",\"num8\":\"80.40\",\"num9\":\"97.40\",\"num10\":9.70,\"num11\":80.40,\"num12\":97.40,\"num13\":9.70,\"num14\":80.40,\"num15\":97.40,\"num16\":9.70,\"num17\":80.40,\"num18\":97.40}}";
    
    NSDictionary *dict = [jsonString mj_JSONObject];
    NSLog(@"dict-%@",dict.description);
    
    Num *num = [Num mj_objectWithKeyValues:dict[@"data"]];
    NSLog(@"num1-%lf",num.num1);
    NSLog(@"num2-%lf",num.num2);
    NSLog(@"num3-%@",@(num.num3));
    NSLog(@"num4-%@",num.num4);
    NSLog(@"num5-%@",num.num5);
    NSLog(@"num6-%@",num.num6);
    NSLog(@"num7-%@",num.num7);
    NSLog(@"num8-%@",num.num8);
    NSLog(@"num9-%@",num.num9);
    NSLog(@"num10-%@",@(num.num10));
    NSLog(@"num11-%@",@(num.num11));
    NSLog(@"num12-%@",@(num.num12));
    NSLog(@"num13-%@",num.num13);
    NSLog(@"num14-%@",num.num14);
    NSLog(@"num15-%@",num.num15);
    NSLog(@"num16-%@",num.num16);
    NSLog(@"num17-%@",num.num17);
    NSLog(@"num18-%@",num.num18);
    
    //后台  string  前端 double    有问题    需要直接经过decimal处理
    //后台  string  前端 nsstring  没问题+小数点后面会带0
    //后台  string  前端 nsnumber  有问题    需要转成double经过decimal处理
    //后台  double  前端 double    有问题    需要直接经过decimal处理
    //后台  double  前端 nsstring  有问题    需要转成double经过decimal处理
    //后台  double  前端 nsnumber  有问题    需要转成double经过decimal处理

    NSArray *array = @[@(num.num1),
                       @(num.num2),
                       @(num.num3),
                       num.num4,
                       num.num5,
                       num.num6,
                       num.num7,
                       num.num8,
                       num.num9,
                       @(num.num10),
                       @(num.num11),
                       @(num.num12),
                       num.num13,
                       num.num14,
                       num.num15,
                       num.num16,
                       num.num17,
                       num.num18];
    
    for (int i = 0; i < 12; i++) {
        UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(40, 90+23*i, 100, 20)];
        //label.text = [array[i] stringValue];
        label.text = decimalNumberWithDouble([array[i] doubleValue]);
        label.backgroundColor = [UIColor redColor];
        label.textColor = [UIColor whiteColor];
        label.numberOfLines = 0;
        [self.view addSubview:label];
    }
    
    [array enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        NSLog(@"%@-%@",@(idx),decimalNumberWithDouble([obj doubleValue]));
    }];
}

NSString *decimalNumberWithDouble(double conversionValue) {
    NSString *doubleString = [NSString stringWithFormat:@"%lf", conversionValue];
    NSDecimalNumber *decNumber = [NSDecimalNumber decimalNumberWithString:doubleString];
    return [decNumber stringValue];
}

打印结果

2021-01-20 15:15:59.947503+0800 OCTest[5698:210724] dict-{
    data =     {
        num1 = "9.70";
        num10 = "9.699999999999999";
        num11 = "80.40000000000001";
        num12 = "97.40000000000001";
        num13 = "9.699999999999999";
        num14 = "80.40000000000001";
        num15 = "97.40000000000001";
        num16 = "9.699999999999999";
        num17 = "80.40000000000001";
        num18 = "97.40000000000001";
        num2 = "80.40";
        num3 = "97.40";
        num4 = "9.70";
        num5 = "80.40";
        num6 = "97.40";
        num7 = "9.70";
        num8 = "80.40";
        num9 = "97.40";
    };
}
2021-01-20 15:15:59.950481+0800 OCTest[5698:210724] num1-9.700000
2021-01-20 15:15:59.950604+0800 OCTest[5698:210724] num2-80.400000
2021-01-20 15:15:59.950700+0800 OCTest[5698:210724] num3-97.40000000000001
2021-01-20 15:15:59.950812+0800 OCTest[5698:210724] num4-9.70
2021-01-20 15:15:59.950898+0800 OCTest[5698:210724] num5-80.40
2021-01-20 15:15:59.950977+0800 OCTest[5698:210724] num6-97.40
2021-01-20 15:15:59.951059+0800 OCTest[5698:210724] num7-9.699999999999999
2021-01-20 15:15:59.951159+0800 OCTest[5698:210724] num8-80.40000000000001
2021-01-20 15:15:59.951340+0800 OCTest[5698:210724] num9-97.40000000000001
2021-01-20 15:15:59.951580+0800 OCTest[5698:210724] num10-9.699999999999999
2021-01-20 15:15:59.951851+0800 OCTest[5698:210724] num11-80.40000000000001
2021-01-20 15:15:59.952132+0800 OCTest[5698:210724] num12-97.40000000000001
2021-01-20 15:15:59.952395+0800 OCTest[5698:210724] num13-9.699999999999999
2021-01-20 15:15:59.952649+0800 OCTest[5698:210724] num14-80.40000000000001
2021-01-20 15:15:59.952902+0800 OCTest[5698:210724] num15-97.40000000000001
2021-01-20 15:15:59.953187+0800 OCTest[5698:210724] num16-9.699999999999999
2021-01-20 15:15:59.959302+0800 OCTest[5698:210724] num17-80.40000000000001
2021-01-20 15:15:59.959404+0800 OCTest[5698:210724] num18-97.40000000000001
2021-01-20 15:15:59.966852+0800 OCTest[5698:210724] 0-9.7
2021-01-20 15:15:59.966976+0800 OCTest[5698:210724] 1-80.4
2021-01-20 15:15:59.967073+0800 OCTest[5698:210724] 2-97.4
2021-01-20 15:15:59.967179+0800 OCTest[5698:210724] 3-9.7
2021-01-20 15:15:59.967279+0800 OCTest[5698:210724] 4-80.4
2021-01-20 15:15:59.967386+0800 OCTest[5698:210724] 5-97.4
2021-01-20 15:15:59.967508+0800 OCTest[5698:210724] 6-9.7
2021-01-20 15:15:59.967618+0800 OCTest[5698:210724] 7-80.4
2021-01-20 15:15:59.967851+0800 OCTest[5698:210724] 8-97.4
2021-01-20 15:15:59.968132+0800 OCTest[5698:210724] 9-9.7
2021-01-20 15:15:59.968417+0800 OCTest[5698:210724] 10-80.4
2021-01-20 15:15:59.968711+0800 OCTest[5698:210724] 11-97.4
2021-01-20 15:15:59.969036+0800 OCTest[5698:210724] 12-9.7
2021-01-20 15:15:59.969353+0800 OCTest[5698:210724] 13-80.4
2021-01-20 15:15:59.969641+0800 OCTest[5698:210724] 14-97.4
2021-01-20 15:15:59.969952+0800 OCTest[5698:210724] 15-9.7
2021-01-20 15:15:59.970228+0800 OCTest[5698:210724] 16-80.4
2021-01-20 15:15:59.970526+0800 OCTest[5698:210724] 17-97.4
WechatIMG39.png

结论:

//后台 string 前端 double 有问题 需要直接经过decimal处理
//后台 string 前端 nsstring 没问题+小数点后面会带0
//后台 string 前端 nsnumber 有问题 需要转成double经过decimal处理
//后台 double 前端 double 有问题 需要直接经过decimal处理
//后台 double 前端 nsstring 有问题 需要转成double经过decimal处理
//后台 double 前端 nsnumber 有问题 需要转成double经过decimal处理

总结:

1.不管什么类型、先转成double然后执行下面代码可解决精度缺失的问题。

NSString *decimalNumberWithDouble(double conversionValue) {
    NSString *doubleString = [NSString stringWithFormat:@"%lf", conversionValue];
    NSDecimalNumber *decNumber = [NSDecimalNumber decimalNumberWithString:doubleString];
    return [decNumber stringValue];
}

2.如果json里面是string类型,前端直接用string,可显示出9.70类似格式的样式,并且不会出现精度缺失的问题。

NSDecimalNumber 分类

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface NSDecimalNumber (Extension)
// doubles->float
+ (float)floatWithDouble:(double)doubles;

// doubles->double
+ (double)doubleWithDouble:(double)doubles;

// 主要使用这两个方法,先把类型转成double
// doubles->NSString
+ (NSString *)stringWithDouble:(double)doubles;

// doubles->NSString-¥
+ (NSString *)stringWithDouble:(double)doubles unit:(NSString *)unit;

// doubles->NSDecimalNumber
+ (NSDecimalNumber *)decimalNumberWithDouble:(double)doubles;

// +
+ (NSString *)multiplyStr1:(NSString *)str1
                      str2:(NSString *)str2;
// -
+ (NSString *)subtractingModelStr1:(NSString *)str1
                              str2:(NSString *)str2;
@end

NS_ASSUME_NONNULL_END

#import "NSDecimalNumber+Extension.h"

@implementation NSDecimalNumber (Extension)
+ (float)floatWithDouble:(double)doubles {
    return [[self decimalNumberWithDouble:doubles] floatValue];
}

+ (double)doubleWithDouble:(double)doubles {
    return [[self decimalNumberWithDouble:doubles] doubleValue];
}

+ (NSString *)stringWithDouble:(double)doubles {
    return [[self decimalNumberWithDouble:doubles] stringValue];
}

+ (NSString *)stringWithDouble:(double)doubles unit:(NSString *)unit{
    NSDecimalNumber *decimalNumber = [NSDecimalNumber decimalNumberWithDouble:doubles];
    return [NSString stringWithFormat:@"%@%@",unit,decimalNumber];;
}

+ (NSDecimalNumber *)decimalNumberWithDouble:(double)doubles {
    NSString *numString = [NSString stringWithFormat:@"%lf", doubles];
    return [NSDecimalNumber decimalNumberWithString:numString];
}

+ (NSString *)multiplyStr1:(NSString *)str1
                             str2:(NSString *)str2 {
    if (kStringIsEmpty(str1)) {
        str1 = @"0";
    }
    if (kStringIsEmpty(str2)) {
        str2 = @"0";
    }
    NSDecimalNumber *decimalNumber1 = [NSDecimalNumber decimalNumberWithString:str1];
    NSDecimalNumber *decimalNumber2 = [NSDecimalNumber decimalNumberWithString:str2];
    NSDecimalNumber *result = [decimalNumber1 decimalNumberByMultiplyingBy:decimalNumber2];
    return [result stringValue];
}

+ (NSString *)subtractingModelStr1:(NSString *)str1
                                     str2:(NSString *)str2 {
    if (kStringIsEmpty(str1)) {
        str1 = @"0";
    }
    if (kStringIsEmpty(str2)) {
        str2 = @"0";
    }
    NSDecimalNumber *decimalNumber1 = [NSDecimalNumber decimalNumberWithString:str1];
    NSDecimalNumber *decimalNumber2 = [NSDecimalNumber decimalNumberWithString:str2];
    NSDecimalNumber *result = [decimalNumber1 decimalNumberBySubtracting:decimalNumber2];
    return [NSString stringWithFormat:@"%@",result];
}
@end

推荐阅读更多精彩内容