Perlfunc: human_size()

Quick function to convert bytes to a human readable string:

my $str = human_size(1536);       # "1.5K"
my $str = human_size(1234567);    # "1.2M"
my $str = human_size(1234567890); # "1.1G"
sub human_size {
    my $size = shift();
    if (!defined($size)) { return undef; }

    if    ($size >= (1024**5) * 0.98) { $size = sprintf("%.1fP", $size / 1024**5); }
    elsif ($size >= (1024**4) * 0.98) { $size = sprintf("%.1fT", $size / 1024**4); }
    elsif ($size >= (1024**3) * 0.98) { $size = sprintf("%.1fG", $size / 1024**3); }
    elsif ($size >= (1024**2) * 0.98) { $size = sprintf("%.1fM", $size / 1024**2); }
    elsif ($size >= 1024)             { $size = sprintf("%.1fK", $size / 1024);    }
    elsif ($size >= 0)                { $size = sprintf("%dB"  , $size);           }

    return $size;
}

Here is the same function implemented in PHP:

function human_size($size) {
    # If the size is 0 or less, return 0 B this stops math errors from occurring
    if ($size <= 0) {
        return '0B';
    } else {
        $unit=array('B','K','M','G','T','P');
        return @round($size/pow(1024,($i=floor(log($size,1024)))),2) . $unit[$i];
    }
}

The same function in C

char buf[8] = "";

human_size(348, buf);
printf("Got: %s\n", buf);

char* humanSize(unsigned long long size, char* str) {
    if (size > 1152921504606846976L) {
        snprintf(str, 7, "%.1fE", (float)size / 1152921504606846976L);
    } else if (size > 1125899906842624L) {
        snprintf(str, 7, "%.1fP", (float)size / 1125899906842624L);
    } else if (size > 1099511627776L) {
        snprintf(str, 7, "%.1fT", (float)size / 1099511627776L);
    } else if (size > 1073741824L) {
        snprintf(str, 7, "%.1fG", (float)size / 1073741824L);
    } else if (size > 1048576L) {
        snprintf(str, 7, "%.1fM", (float)size / 1048576L);
    } else if (size > 1024) {
        snprintf(str, 7, "%.1fK", (float)size / 1024);
    } else if (size <= 1024) {
        snprintf(str, 7, "%uB", (unsigned)size);
    }

    return str;
}
Leave A Reply - 1 Reply
Replies
David Edwards 2006-11-30 09:10am - dave@... - Logged IP: 65.115.220.76

I've done similar, I ended up doing all the things manually though, such as inputting 1048576 to the code instead of multiplication. I'm sure the compiler/interpreter can take care of it just fine either way though. ;)

All content licensed under the Creative Commons License