iOS 解决浮点型字符串转化不准确的问题

简介

ios开发中有时我们需要把NSNumber转化为NSString类型,会出现转化不准确的现象.

比如后台定义了一个82.4,我们接收到数据,并转化为NSString类型,结果会显示出82.39999999999999999.试过几次后发现是double转化为NSNumber的时候除了问题.

double表示的字面值和其存储的值一般是不一样的,转化为NSNumber之后,有很大一些数字,在NSNumberstringValue上会出错。

解决方法:

可以是取NSStringdoubleValue,然后再.2f保留两位小数进行构造字符串。千万不能取floatValuefloatValue在大于15万的浮点数字就会出现不精确了 。而doubleValue在数十亿的范围内都是字面上精确的。

如果涉及到计算的问题,需要把字符串转化为NSDecimalNumber对象,再转成字符串。

下面附上一套格式化数字类型字符串的方法:

typedef NS_ENUM(NSUInteger, EHNumberFormatterStyle) {

  EHNumberFormatterIntegerStyle = 0,//123,456,7
  EHNumberFormatterDecimalStyle,    //12,345.67
  EHNumberFormatterFractionDecimalStyle,    // 小数为0舍去  12,345.0 => 12,345  12,345.1=>12,345.1
  EHNumberFormatterCurrencyPrefixIntegerStyle, //¥123,456,7
  EHNumberFormatterCurrencySuffixIntegerStyle, //123,456,7元
  EHNumberFormatterCurrencySuffixDecimalStyle, //12,345.67元
  EHNumberFormatterCurrencyTenThousandStyle,   //123万
  EHNumberFormatterCurrencyTenThousandDecimalStyle, //123.4万
  EHNumberFormatterAreaStyle, //123m²
  EHNumberFormatterAreaPriceStyle, //1,234元/m²
  EHNumberFormatterRentPriceStyle, //1,234元/月
  EHNumberFormatterPercentStyle,   // +1.23% , -1.23%
  EHNumberFormatterUnsignedPercentStyle   // 1.23% -1.23%

 };

/*
 style 格式化类型
 decimalPlace 精确度
 symbol 为空时返回字符串
 prefix 正负符号的追加格式
 suffix 单位符号的追加格式
 */
+(NSString *)stringWithNumberStyle:(EHNumberFormatterStyle)style data:(id)data decimalPlace:(NSInteger)decimalPlace nullOrZeroSymbol:(NSString*)symbol prefix:(NSString*)prefix suffix:(NSString*)suffix{

  NSNumberFormatter *formatter;
  NSNumber *num;

  if(![data isKindOfClass:[NSString class]] && ![data isKindOfClass:[NSNumber class]]){
      num = @(0);
  }

  if([data isKindOfClass:[NSString class]]){
    
    formatter = [[NSNumberFormatter alloc] init];
    
    formatter.numberStyle = NSNumberFormatterDecimalStyle;
    
    num = [formatter numberFromString:data];
    
    if(!num) num = @(0);
 
  }else{
    num = data;
  }


  NSString *result;

  if(num && num.boolValue){
    if(style == EHNumberFormatterIntegerStyle)
    {
        formatter = [self formatterFromNumberStyle:EHNumberFormatterIntegerStyle decimalPlace:decimalPlace];
        result = [formatter stringFromNumber:num];
    }
    else if(style == EHNumberFormatterDecimalStyle)
    {
        formatter = [self formatterFromNumberStyle:EHNumberFormatterDecimalStyle decimalPlace:decimalPlace];
        result = [formatter stringFromNumber:num];
    }
    else if(style == EHNumberFormatterFractionDecimalStyle)
    {
        formatter = [self formatterFromNumberStyle:EHNumberFormatterFractionDecimalStyle decimalPlace:decimalPlace];
        result = [formatter stringFromNumber:num];
    }
    else if(style == EHNumberFormatterCurrencyPrefixIntegerStyle)
    {
        result = [self stringWithNumberStyle:EHNumberFormatterIntegerStyle data:data decimalPlace:decimalPlace nullOrZeroSymbol:symbol prefix:@"¥" suffix:@""];
    }
    else if(style == EHNumberFormatterCurrencyPrefixDecimalStyle)
    {
        result = [self stringWithNumberStyle:EHNumberFormatterDecimalStyle data:data decimalPlace:decimalPlace nullOrZeroSymbol:symbol prefix:@"¥" suffix:@""];
    }
    else if(style == EHNumberFormatterCurrencySuffixIntegerStyle)
    {
        result = [self stringWithNumberStyle:EHNumberFormatterIntegerStyle data:data decimalPlace:decimalPlace nullOrZeroSymbol:symbol prefix:@"" suffix:@"元"];
    }
    else if(style == EHNumberFormatterCurrencySuffixDecimalStyle)
    {
        result = [self stringWithNumberStyle:EHNumberFormatterDecimalStyle data:data decimalPlace:decimalPlace nullOrZeroSymbol:symbol prefix:@"" suffix:@"元"];
    }
    else if(style == EHNumberFormatterCurrencyTenThousandStyle)
    {
        num = @(num.doubleValue/10000);
        result = [self stringWithNumberStyle:EHNumberFormatterIntegerStyle data:data decimalPlace:decimalPlace nullOrZeroSymbol:symbol prefix:@"" suffix:@"万"];
    }
    else if(style == EHNumberFormatterCurrencyTenThousandDecimalStyle)
    {
        num = @(num.doubleValue/10000);
        result = [self stringWithNumberStyle:EHNumberFormatterFractionDecimalStyle data:data decimalPlace:decimalPlace nullOrZeroSymbol:symbol prefix:@"" suffix:@"万"];
    }
    else if(style == EHNumberFormatterAreaStyle)
    {
        result = [self stringWithNumberStyle:EHNumberFormatterFractionDecimalStyle data:data decimalPlace:decimalPlace nullOrZeroSymbol:symbol prefix:@"" suffix:@"m²"];
    }
    else if(style == EHNumberFormatterAreaPriceStyle)
    {
        result = [self stringWithNumberStyle:EHNumberFormatterIntegerStyle data:data decimalPlace:decimalPlace nullOrZeroSymbol:symbol prefix:@"" suffix:@"元/m²"];
    }
    else if(style == EHNumberFormatterRentPriceStyle)
    {
        result = [self stringWithNumberStyle:EHNumberFormatterIntegerStyle data:data decimalPlace:decimalPlace nullOrZeroSymbol:symbol prefix:@"" suffix:@"元/月"];
    }
    else if(style == EHNumberFormatterPercentStyle)
    {
        result = [self stringWithNumberStyle:EHNumberFormatterDecimalStyle data:data decimalPlace:decimalPlace nullOrZeroSymbol:symbol prefix:[num doubleValue]>=0?@"+":@"" suffix:@"%"];
    }
    else if(style == EHNumberFormatterUnsignedPercentStyle)
    {
        result = [self stringWithNumberStyle:EHNumberFormatterDecimalStyle data:data decimalPlace:decimalPlace nullOrZeroSymbol:symbol prefix:@"" suffix:@"%"];
    }
}


  if([result eh_hasData]){
    result = [NSString stringWithFormat:@"%@%@%@",prefix,result,suffix];
  }else{
    result = symbol ?: @"";
  }
  return result;
}


+(NSNumberFormatter*)formatterFromNumberStyle:(EHNumberFormatterStyle)style decimalPlace:(NSInteger)decimalPlace{

  NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];

  if(style == EHNumberFormatterIntegerStyle)
  {
    formatter = [[NSNumberFormatter alloc] init];
    formatter.groupingSize = 3;
    formatter.groupingSeparator = @",";
    formatter.usesGroupingSeparator = NO;
  }
  else if(style == EHNumberFormatterDecimalStyle)
  {
    formatter = [[NSNumberFormatter alloc] init];
    formatter.numberStyle = NSNumberFormatterDecimalStyle;
    formatter.roundingMode = NSNumberFormatterRoundCeiling;
    formatter.maximumFractionDigits = decimalPlace;
    formatter.minimumFractionDigits = decimalPlace;
  }
  else if(style == EHNumberFormatterFractionDecimalStyle)
  {
    formatter = [[NSNumberFormatter alloc] init];
    formatter.numberStyle = NSNumberFormatterDecimalStyle;
    formatter.roundingMode = NSNumberFormatterRoundCeiling;
    formatter.maximumFractionDigits = decimalPlace;
  }
  return formatter;
}

你可能感兴趣的:(iOS 解决浮点型字符串转化不准确的问题)