iOS開發
項目中用到了將一個很大的數值轉換成科學計數法的需求,轉換成科學計數法的方式在iOS中其實是很好做的,使用NSNumber 的 kCFNumberFormatterScientificStyle就可以把指定的數值轉換成帶‘E’后綴的科學計數法字符串了。
由於項目中的特定的需求,NSNumber轉換成科學計數法后,后面的小數位無法控制,有些數字很大的時候,小數位甚至會有幾十位,導致無法將科學計數法的真實值完全顯示出來。這里提供一種方案,可以實現將結果轉換成指定位數小數的科學計數法結果,代碼如下:
/*
科學計數法,保留n個有效值
*/
-(NSString *) toExponent:(double)d rms:(NSInteger)n
{
if(n==0)
{
return nil;
}
//科學計算法 一般寫法4.232E這種樣式 這里的n代表所有數字的個數 所以這里n++
n++;
//判斷小數的位數是否超過設定的n的值 如果超過了保留n位有效數字 如果不超過則保留默認小數位數
//先將double轉換成字符串
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSString *dbStr = [formatter stringFromNumber:[NSDecimalNumber numberWithDouble:d]];
NSInteger length = dbStr.length;
if ([dbStr containsString:@"."]) {
length = dbStr.length - 1;
}
if (length < n) {
n = length;
}
CFLocaleRef currentLocale = CFLocaleCopyCurrent();
CFNumberFormatterRef customCurrencyFormatter = CFNumberFormatterCreate
(NULL, currentLocale, kCFNumberFormatterCurrencyStyle);
NSString *s_n = @"#";
if(n > 1)
{
for(int j = 0; j < n; j++)
{
NSString *temp = s_n;
if(j == 0)
{
s_n = [temp stringByAppendingString:@"."];
}
else
{
s_n = [temp stringByAppendingString:@"0"];
}
}
}
CFNumberFormatterSetFormat(customCurrencyFormatter, (CFStringRef)s_n);
double i=1;
int exponent = 0;
while (1) {
i = i*10;
if(d < i)
{
break;
}
exponent++;
}
double n1 = d * 10 / i;
CFNumberRef number1 = CFNumberCreate(NULL, kCFNumberDoubleType, &n1);
CFStringRef string1 = CFNumberFormatterCreateStringWithNumber
(NULL, customCurrencyFormatter, number1);
NSLog(@"%@", (__bridge NSString *)string1);
NSString * result = [NSString stringWithFormat:@"%@e%d",(__bridge NSString *)string1,exponent];
CFRelease(currentLocale);
CFRelease(customCurrencyFormatter);
CFRelease(number1);
CFRelease(string1);
return result;
}