簡介
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ù)字,在NSNumber
的stringValue
上會出錯锯七。
解決方法:
可以是取NSString
的doubleValue
,然后再.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;
}