iOS 解決浮點型字符串轉(zhuǎn)化不準確的問題

簡介

ios開發(fā)中有時我們需要把NSNumber轉(zhuǎn)化為NSString類型,會出現(xiàn)轉(zhuǎn)化不準確的現(xiàn)象.

比如后臺定義了一個82.4,我們接收到數(shù)據(jù),并轉(zhuǎn)化為NSString類型,結(jié)果會顯示出82.39999999999999999.試過幾次后發(fā)現(xiàn)是double轉(zhuǎn)化為NSNumber的時候除了問題.

double表示的字面值和其存儲的值一般是不一樣的夷狰,轉(zhuǎn)化為NSNumber之后门怪,有很大一些數(shù)字,在NSNumberstringValue上會出錯锯七。

解決方法:

可以是取NSStringdoubleValue,然后再.2f保留兩位小數(shù)進行構(gòu)造字符串挤聘。千萬不能取floatValue舷手,floatValue在大于15萬的浮點數(shù)字就會出現(xiàn)不精確了 。而doubleValue在數(shù)十億的范圍內(nèi)都是字面上精確的拾酝。

如果涉及到計算的問題燕少,需要把字符串轉(zhuǎn)化為NSDecimalNumber對象,再轉(zhuǎn)成字符串蒿囤。

下面附上一套格式化數(shù)字類型字符串的方法:

typedef NS_ENUM(NSUInteger, EHNumberFormatterStyle) {

  EHNumberFormatterIntegerStyle = 0,//123,456,7
  EHNumberFormatterDecimalStyle,    //12,345.67
  EHNumberFormatterFractionDecimalStyle,    // 小數(shù)為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, //123m2
  EHNumberFormatterAreaPriceStyle, //1,234元/m2
  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:@"m2"];
    }
    else if(style == EHNumberFormatterAreaPriceStyle)
    {
        result = [self stringWithNumberStyle:EHNumberFormatterIntegerStyle data:data decimalPlace:decimalPlace nullOrZeroSymbol:symbol prefix:@"" suffix:@"元/m2"];
    }
    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;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末客们,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子材诽,更是在濱河造成了極大的恐慌底挫,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件脸侥,死亡現(xiàn)場離奇詭異建邓,居然都是意外死亡,警方通過查閱死者的電腦和手機湿痢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門涝缝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來扑庞,“玉大人,你說我怎么就攤上這事拒逮」薨保” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵滩援,是天一觀的道長栅隐。 經(jīng)常有香客問我,道長玩徊,這世上最難降的妖魔是什么租悄? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮恩袱,結(jié)果婚禮上泣棋,老公的妹妹穿的比我還像新娘。我一直安慰自己畔塔,他們只是感情好潭辈,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著澈吨,像睡著了一般把敢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谅辣,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天修赞,我揣著相機與錄音,去河邊找鬼桑阶。 笑死柏副,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的蚣录。 我是一名探鬼主播搓扯,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼包归!你這毒婦竟也來了锨推?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤公壤,失蹤者是張志新(化名)和其女友劉穎换可,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體厦幅,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡沾鳄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了确憨。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片译荞。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡瓤的,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吞歼,到底是詐尸還是另有隱情圈膏,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布篙骡,位于F島的核電站稽坤,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏糯俗。R本人自食惡果不足惜尿褪,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望得湘。 院中可真熱鬧杖玲,春花似錦、人聲如沸淘正。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽跪帝。三九已至,卻和暖如春些阅,著一層夾襖步出監(jiān)牢的瞬間伞剑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工市埋, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留黎泣,地道東北人。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓缤谎,卻偏偏與公主長得像抒倚,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子坷澡,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容