views:

443

answers:

5

I'd like to get the first three digits from large floats or integers and on some insert a decimal. For example:

KB
----------
32589 >> 325
43266 >> 432

MB
----------
1234599 >> 1.23
3422847 >> 3.42

For the particular number, I will have the "KB" and "MB" strings. This will let me know if the decimal is required, as in "MB" examples. I looked at NSNumberFormatter but wasn't sure what on there would help. Any suggestions?

+1  A: 

You can do this by converting the number into a text representation using itoa or sprintf or implementing your own version of this conversion technique. Once this is done, you can pull the first three characters from the text buffer to use.

Joe Corkery
+1  A: 

Probably the easiest way to deal with this is to convert it to a string and use one of the cocoadev regex libraries to do the formatting

ennuikiller
+5  A: 

Wait, are you trying to say 32589 bytes is 325 KB?

Wouldn't it make sense to divide the number by 1000 repeatedly until the result is less than 1000, then format with whatever printf equivalent you have?

glenn jackman
This is the correct answer. We're looking at integers here folks, don't go around allocating chunks of memory and doing byte-for-byte comparisons when you can just do 'while (x > 1000) x = (x / 10);'
Jim Dovey
+1  A: 

Here is some quick & dirty code to pull off the top three digits of the number (in NSString format):

long someNumber = 1234599;
NSString * allDigits = [NSString stringWithFormat:@"%l", someNumber];
NSString * topDigits = [allDigits substringToIndex:3];

NSLog(@"%@", topDigits); // will output 123
e.James
+2  A: 

Actually, decided to chime in with my own answer. This is my routine for generating strings for outputting human sizes from byte counts:

#include <math.h>    // for isgreater()
static NSString * MemorySizeString( mach_vm_size_t size )
{
    enum
    {
        kSizeIsBytes        = 0,
        kSizeIsKilobytes,
        kSizeIsMegabytes,
        kSizeIsGigabytes,
        kSizeIsTerabytes,
        kSizeIsPetabytes,
        kSizeIsExabytes
    };

    int sizeType = kSizeIsBytes;
    double dSize = (double) size;

    while ( isgreater(dSize, 1024.0) )
    {
        dSize = dSize / 1024.0;
        sizeType++;
    }

    NSMutableString * str = [[NSMutableString alloc] initWithFormat: (sizeType == kSizeIsBytes ? @"%.00f" : @"%.02f"), dSize];
    switch ( sizeType )
    {
        default:
        case kSizeIsBytes:
            [str appendString: @" bytes"];
            break;

        case kSizeIsKilobytes:
            [str appendString: @"KB"];
            break;

        case kSizeIsMegabytes:
            [str appendString: @"MB"];
            break;

        case kSizeIsGigabytes:
            [str appendString: @"GB"];
            break;

        case kSizeIsTerabytes:
            [str appendString: @"TB"];
            break;

        case kSizeIsPetabytes:
            [str appendString: @"PB"];
            break;

        case kSizeIsExabytes:
            [str appendString: @"EB"];
            break;
    }

    NSString * result = [str copy];
    [str release];

    return ( [result autorelease] );
}

It works out the correct size by seeing what order of binary magnitude it is, using 1024 as the base (1024 bytes = 1KB, 1024KB = 1MB, etc.). While doing this, it shrinks the input value (using floating-point arithmetic) such that once it's below 1024, it has both a human-readable value and a magnitude specifier. It then generates a string containing the formatted value (no decimal places for bytes, 2 decimal places for any larger magnitude), and inspects the magnitude constant to determine what suffix to attach.

Jim Dovey
Awesome! I was wondering about creating an enum for it. Thanks. Looks like you are pulling this from Cocoa. This is for iPhone development, which is all Cocoa Touch. What is mach_vm_size_t?
4thSpace
mach_vm_size_t is a the low-level type definition for a virtual memory size variable; on the iPhone it's an unsigned 32-bit integer. The code above comes from a memory-visualizing view I designed to help me debug allocation amounts in Outpost, so it has to use Mach APIs to get the amount of used memory in the process's address space.
Jim Dovey
I just put the memory-fetching code <a href="http://gist.github.com/112269">on github</a> if that's useful for you.
Jim Dovey
Okay, grrr, comments can't use HTML. http://gist.github.com/112269 is where you'll find it.
Jim Dovey