iOS - Json解析精度丢失处理(NSString, Double, Float)
Posted 沈成才
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS - Json解析精度丢失处理(NSString, Double, Float)相关的知识,希望对你有一定的参考价值。
前几天在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];
强烈建议 : 有关浮点型数据,后台传字符串的格式,防止丢失精度。
以上是关于iOS - Json解析精度丢失处理(NSString, Double, Float)的主要内容,如果未能解决你的问题,请参考以下文章
iOS - Json解析精度丢失处理(NSString, Double, Float)
当预期类型可能不同时,如何安全地处理来自 JSON 的数据?
前后的交互js数字精度丢失解决,金额保留两位小数四舍五入统一解决,自定义Json序列化处理方法,@JsonSerialize使用