iOS convert large numbers to smaller format iOS convert large numbers to smaller format ios ios

iOS convert large numbers to smaller format


-(NSString*) suffixNumber:(NSNumber*)number{    if (!number)        return @"";    long long num = [number longLongValue];    int s = ( (num < 0) ? -1 : (num > 0) ? 1 : 0 );    NSString* sign = (s == -1 ? @"-" : @"" );    num = llabs(num);    if (num < 1000)        return [NSString stringWithFormat:@"%@%lld",sign,num];    int exp = (int) (log10l(num) / 3.f); //log10l(1000));    NSArray* units = @[@"K",@"M",@"G",@"T",@"P",@"E"];    return [NSString stringWithFormat:@"%@%.1f%@",sign, (num / pow(1000, exp)), [units objectAtIndex:(exp-1)]];}

sample usage

NSLog(@"%@",[self suffixNumber:@100]); // 100NSLog(@"%@",[self suffixNumber:@1000]); // 1.0KNSLog(@"%@",[self suffixNumber:@1500]); // 1.5KNSLog(@"%@",[self suffixNumber:@24000]); // 24.0KNSLog(@"%@",[self suffixNumber:@99900]); // 99.9KNSLog(@"%@",[self suffixNumber:@99999]); // 100.0KNSLog(@"%@",[self suffixNumber:@109999]); // 110.0KNSLog(@"%@",[self suffixNumber:@5109999]); // 5.1MNSLog(@"%@",[self suffixNumber:@8465445223]); // 8.5GNSLog(@"%@",[self suffixNumber:[NSNumber numberWithInt:-120]]); // -120NSLog(@"%@",[self suffixNumber:[NSNumber numberWithLong:-5000000]]); // -5.0MNSLog(@"%@",[self suffixNumber:[NSNumber numberWithDouble:-3.5f]]); // -3NSLog(@"%@",[self suffixNumber:[NSNumber numberWithDouble:-4000.63f]]); // -4.0K

[Update]

Swift version below:

func suffixNumber(number:NSNumber) -> NSString {    var num:Double = number.doubleValue;    let sign = ((num < 0) ? "-" : "" );    num = fabs(num);    if (num < 1000.0){        return "\(sign)\(num)";    }    let exp:Int = Int(log10(num) / 3.0 ); //log10(1000));    let units:[String] = ["K","M","G","T","P","E"];    let roundedNum:Double = round(10 * num / pow(1000.0,Double(exp))) / 10;    return "\(sign)\(roundedNum)\(units[exp-1])";}

sample usage

print(self.suffixNumber(NSNumber(long: 100))); // 100.0print(self.suffixNumber(NSNumber(long: 1000))); // 1.0Kprint(self.suffixNumber(NSNumber(long: 1500))); // 1.5Kprint(self.suffixNumber(NSNumber(long: 24000))); // 24.0Kprint(self.suffixNumber(NSNumber(longLong: 99900))); // 99.9Kprint(self.suffixNumber(NSNumber(longLong: 99999))); // 100.0Kprint(self.suffixNumber(NSNumber(longLong: 109999))); // 110.0Kprint(self.suffixNumber(NSNumber(longLong: 5109999))); // 5.1Kprint(self.suffixNumber(NSNumber(longLong: 8465445223))); // 8.5Gprint(self.suffixNumber(NSNumber(long: -120))); // -120.0print(self.suffixNumber(NSNumber(longLong: -5000000))); // -5.0Mprint(self.suffixNumber(NSNumber(float: -3.5))); // -3.5print(self.suffixNumber(NSNumber(float: -4000.63))); // -4.0K

Hope it helps


Here my version ! Thanks to previous answers.The goals of this version is :

  • Have better threshold control because small number details are more important that very big number details
  • Use as much as possible NSNumberFormatter to avoid location problems (like comma instead of dot in french)
  • Avoid ".0" and well rounding numbers, which can be customize using NSNumberFormatterRoundingMode

You can use all wonderful NSNumberFormatter options to fulfill your needs, see NSNumberFormatter Class Reference

The code (gist):

extension Int {    func formatUsingAbbrevation () -> String {        let numFormatter = NSNumberFormatter()        typealias Abbrevation = (threshold:Double, divisor:Double, suffix:String)        let abbreviations:[Abbrevation] = [(0, 1, ""),                                           (1000.0, 1000.0, "K"),                                           (100_000.0, 1_000_000.0, "M"),                                           (100_000_000.0, 1_000_000_000.0, "B")]                                           // you can add more !        let startValue = Double (abs(self))        let abbreviation:Abbrevation = {            var prevAbbreviation = abbreviations[0]            for tmpAbbreviation in abbreviations {                if (startValue < tmpAbbreviation.threshold) {                    break                }                prevAbbreviation = tmpAbbreviation            }            return prevAbbreviation        } ()        let value = Double(self) / abbreviation.divisor        numFormatter.positiveSuffix = abbreviation.suffix        numFormatter.negativeSuffix = abbreviation.suffix        numFormatter.allowsFloats = true        numFormatter.minimumIntegerDigits = 1        numFormatter.minimumFractionDigits = 0        numFormatter.maximumFractionDigits = 1        return numFormatter.stringFromNumber(NSNumber (double:value))!    }}let testValue:[Int] = [598, -999, 1000, -1284, 9940, 9980, 39900, 99880, 399880, 999898, 999999, 1456384, 12383474]testValue.forEach() {    print ("Value : \($0) -> \($0.formatUsingAbbrevation ())")}

Result :

Value : 598 -> 598Value : -999 -> -999Value : 1000 -> 1KValue : -1284 -> -1.3KValue : 9940 -> 9.9KValue : 9980 -> 10KValue : 39900 -> 39.9KValue : 99880 -> 99.9KValue : 399880 -> 0.4MValue : 999898 -> 1MValue : 999999 -> 1MValue : 1456384 -> 1.5MValue : 12383474 -> 12.4M


I had the same issue and ended up using Kyle's approach but unfortunately it breaks when numbers like 120000 are used, showing 12k instead of 120K and I needed to show small numbers like: 1.1K instead of rounding down to 1K.

So here's my edit from Kyle's original idea:

Results:[self abbreviateNumber:987] ---> 987[self abbreviateNumber:1200] ---> 1.2K[self abbreviateNumber:12000] ----> 12K[self abbreviateNumber:120000] ----> 120K[self abbreviateNumber:1200000] ---> 1.2M[self abbreviateNumber:1340] ---> 1.3K[self abbreviateNumber:132456] ----> 132.5K-(NSString *)abbreviateNumber:(int)num {NSString *abbrevNum;float number = (float)num;//Prevent numbers smaller than 1000 to return NULLif (num >= 1000) {    NSArray *abbrev = @[@"K", @"M", @"B"];    for (int i = abbrev.count - 1; i >= 0; i--) {        // Convert array index to "1000", "1000000", etc        int size = pow(10,(i+1)*3);        if(size <= number) {            // Removed the round and dec to make sure small numbers are included like: 1.1K instead of 1K            number = number/size;            NSString *numberString = [self floatToString:number];            // Add the letter for the abbreviation            abbrevNum = [NSString stringWithFormat:@"%@%@", numberString, [abbrev objectAtIndex:i]];        }    }} else {    // Numbers like: 999 returns 999 instead of NULL    abbrevNum = [NSString stringWithFormat:@"%d", (int)number];}return abbrevNum;}- (NSString *) floatToString:(float) val {NSString *ret = [NSString stringWithFormat:@"%.1f", val];unichar c = [ret characterAtIndex:[ret length] - 1];while (c == 48) { // 0    ret = [ret substringToIndex:[ret length] - 1];    c = [ret characterAtIndex:[ret length] - 1];    //After finding the "." we know that everything left is the decimal number, so get a substring excluding the "."    if(c == 46) { // .        ret = [ret substringToIndex:[ret length] - 1];    }}return ret;}

I Hope this can help you guys.