iOS - Json解析精度丢失处理(NSString, Double, Float)

来源:互联网 发布:苹果安装windows系统 编辑:程序博客网 时间:2024/05/02 00:04

前几天在IOS开发时发现一个JSON解析奇葩问题,会出现一定概率的错误,如下:

//出现BUG的条件必须是两位数,且带两位小数,类型还必须是float    //两位数:十位必须是7、8、9;个位数随意    //两位小数:个位数随意;十位数必须是0    NSString *jsonStr = @"{\"71.40\":71.40, \"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);    /*结果:dic:{     "188.40" = "188.4";     "71.40" = "71.40000000000001";     "80.40" = "80.40000000000001";     "97.30" = "97.3";     }*/

初步怀疑是系统API内部处理问题。
在苹果解决这个问题之前,作为开发者,如下可以用来作为开发过程中这类问题不可避免时的方案:
过测试其实系统NSDecimalNumber是对有问题值做了四舍五入处理

还有经过测试, 重要的事说三遍:
处理精度有关的数据请用double
处理精度有关的数据请用double
处理精度有关的数据请用double

double testDouble = [jsonDict[@"Body"][@"Amount"] double]; //有问题 90.989999999999994    NSString *convertString = decimalNumberWithString([jsonDict[@"Body"][@"Amount"] stringValue]);    NSLog(@"%@", convertString);       testDouble的值     原始值& NSDecimalNumber处理后打印后的值//    99.489999999999994 99.49//    99.989999999999994 99.99//    90                 90.00//    90.090000000000003 90.09//    90.189999999999998 90.19//    90.290000000000006 90.29//    90.39              90.39//    90.489999999999994 90.49//    90.590000000000003 90.59//    90.689999999999998 90.69//    90.790000000000006 90.79//    90.89              90.89//    90.989999999999994 90.99

对此自己写了个方法处理

/** 直接传入精度丢失有问题的Double类型*/NSString *decimalNumberWithDouble(double conversionValue){    NSString *doubleString        = [NSString stringWithFormat:@"%lf", conversionValue];    NSDecimalNumber *decNumber    = [NSDecimalNumber decimalNumberWithString:doubleString];    return [decNumber stringValue];}

强烈建议 : 有关浮点型数据,后台传字符串的格式,防止丢失精度。

1 0