美文网首页iOS开发ios基础iOS开发常用知识点
iOS 处理浮点类型精度丢失问题

iOS 处理浮点类型精度丢失问题

作者: 青苹果园 | 来源:发表于2017-09-01 23:43 被阅读803次

1. 问题:

在iOS开发中,我们经常要使用浮点类型去接收后台返回过来的的数据,这时往往会遇到精度问题,特别是在开发金融类APP的时候,例如:

// 后台返回数据中price为71.49:  
NSString * jsonStr = @"{\"price\":71.49}"; 
NSData *jsonData = [jsonStr dataUsingEncoding:NSUTF8StringEncoding]; 
NSDictionary *json = [NSMutableDictionary dictionaryWithDictionary:[NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil]];
NSLog(@"处理之前:%@", [json[@"price"] stringValue]);
// 当我们用浮点类型去接收的时: price = 71.48999999999999

2. 苹果提供的解决方案:NSDecimalNumber

苹果针对浮点型计算时存在精度计算误差的问题,而提供的一个NSDecimalNumber的计算类。
NSDecimalNumber继承于NSNumber,它可以是正(负)小数的10进制数,通过定点计算保证了精度不会缺失。
NSDecimalNumber可以定制四种精度的取正类型分别是:向上取正、向下取正、四舍五入和特殊的四舍五入(碰到保留位数后一位的数字为5时,根据前一位的奇偶性决定。为偶时向下取正,为奇数时向上取正如:1.25保留1为小数。5之前是2偶数向下取正1.2;1.35保留1位小数时。5之前为3奇数,向上取正1.4)。
相对与浮点类型的计算,NSDecimalNumber提供了更加精准的计算。

3. 居于NSDecimalNumber的处理方案:

  1. 直接让后台返回一个字符串,用NSDecimalNumber处理计算问题;
  2. 后台传浮点类型,用NSDecimalNumber处理精度丢失问题。
  • 这里我直接使用一个继承于NSObjec的工具类LSLDecimalNumberTool来处理,实现如下:
@implementation LSLDecimalNumberTool

+ (float)floatWithdecimalNumber:(double)num {
    return [[self decimalNumber:num] floatValue];
}

+ (double)doubleWithdecimalNumber:(double)num {
    return [[self decimalNumber:num] doubleValue];
}

+ (NSString *)stringWithDecimalNumber:(double)num {
    return [[self decimalNumber:num] stringValue];
}

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

@end
  • 接着上面的代码,使用NSDecimalNumber来处理之后的数据:
NSLog(@"------------------");
NSString *priceStr = [LSLDecimalNumberTool stringWithDecimalNumber:[json[@"price"] doubleValue]];
NSLog(@"处理之后:%@", priceStr);
  • 运行结果:
// 运行结果:
2017-09-01 23:32:20.340917+0800 DecimalNumberDemo[4006:1155999] 处理之前:71.48999999999999
2017-09-01 23:32:20.340977+0800 DecimalNumberDemo[4006:1155999] ------------------
2017-09-01 23:32:20.341049+0800 DecimalNumberDemo[4006:1155999] 处理之后:71.49

最后在处理精度问题时,建议两点:

  1. 处理精度有关的数据请使用double;
  2. 最好直接让后台返回字符串类型。

相关文章

  • iOS 处理浮点类型精度丢失问题

    1. 问题: 在iOS开发中,我们经常要使用浮点类型去接收后台返回过来的的数据,这时往往会遇到精度问题,特别是在开...

  • iOS 浮点类型精度丢失问题

    苹果提供的解决方案:NSDecimalNumber 针对浮点类型计算精度问题提供的计算类,基于十进制的科学计数法来...

  • 小问题整理

    1.iOS11数字精度问题 /*! @brief 修正浮点型精度丢失 @param str 传入接口取到的数据 @...

  • Java浮点类型精度丢失问题

    一、问题 二、分析我们把十进制的0.3转为二进制 小数类型转化为二进制方法: 小数乘以2得到b,取b的整数位,如果...

  • iOS数据模型化时浮点数精度丢失

    iOS数据模型化时当json中有浮点数时,会出现浮点数精度丢失的问题如:@"{"number":"22.5"}"转...

  • 关于浮点型精度问题的一些理解

    这是一篇关于浮点型精度的文章,大致会从三个大的问题入手,去解析精度问题。 字符串转浮点型出现精度丢失 浮点型和浮点...

  • py_28 Decimal处理小数计算精度问题

    python Decimal这个类处理浮点数精度 浮点数在内存中存储的时候因为存储机制的原因,天然存在精度丢失的现...

  • iOS - Json解析精度丢失处理(NSString, Dou

    开发中处理处理价格金额问题, 后台经常返回float类型, 打印或转成NSString都会有精度丢失问题, 因此使...

  • 精度丢失

    开发中处理处理价格金额问题, 后台经常返回float、double类型, 打印或转成NSString都会有精度丢失...

  • iOS浮点数精度丢失问题及处理方案

    为什么浮点数精度会丢失 浮点十进制值通常没有完全相同的二进制表示形式。 这是 CPU 所采用的浮点数据表示形式的副...

网友评论

本文标题:iOS 处理浮点类型精度丢失问题

本文链接:https://www.haomeiwen.com/subject/cpkljxtx.html