iOS json解析过程中float转字符串精度丢失的问题 修正NSJSONSerialization

陆卓
2023-12-01

ios在获取json数据后通常使用NSJSONSerialization解析成字典便于使用

NSData *jsonData_ = [html dataUsingEncoding:NSUTF8StringEncoding];
NSError *jsonParsingError_ = nil;
NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:[NSJSONSerialization JSONObjectWithData:jsonData_ options:0 error:&jsonParsingError_]];

在对于

NSString *html = @"{\"71.40\":71.40,\"8.37\":8.37,\"80.40\":80.40,\"188.40\":188.40}";

这样的小数会出现精度丢失问题

会得到

"188.40" = "188.4";
"71.40" = "71.40000000000001";
"8.37" = "8.369999999999999";
"80.40" = "80.40000000000001";

这样的字典

一种办法是更换解析库,尝试SBJSON可以正确解析,但是SBJSON库有一些别的问题,还是希望用原生解析,

另一种办法是取的时候修正,使用

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

对需要的value使用这个方法,缺点是用的时候容易忘记

 

写了一个方法统一对字典进行纠正。

NSString *html = @"{\"71.40\":71.40,\"8.37\":8.37,\"80.40\":80.40,\"188.40\":188.40}";//模拟器处理耗时0.000379秒

NSData *jsonData_ = [html dataUsingEncoding:NSUTF8StringEncoding];
NSError *jsonParsingError_ = nil;
NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:[NSJSONSerialization JSONObjectWithData:jsonData_ options:0 error:&jsonParsingError_]];
NSLog(@"dic:%@", dic);
dic=[dic correctDecimalLoss:dic];
NSLog(@"dic:%@", dic);

使用correctDecimalLoss:后只需几毫秒会遍历字典内内容进行修正

完整文件代码在https://github.com/gwh111/bench_ios/blob/master/bench_ios/bench/CC_Foundation/CC_Lib%2BNSDictionary.m

也可使用pod安装bench_ios这个辅助库

 

 类似资料: