Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

Module for file size arithmetic

by mirod (Canon)
on Mar 12, 2009 at 10:07 UTC ( #750114=perlquestion: print w/replies, xml ) Need Help??

mirod has asked for the wisdom of the Perl Monks concerning the following question:

I am looking for a module that would let me do file size arithmetic from human readable sizes: add( "1 Gb", "500 Mb") would give me "1.5 Gb", add( "753 Mb", "50 Kb") would still give me "753 Mb".

I have searched CPAN and the Monastery, but didn't find anything. Is there such a module, or at least a combination of 2 modules, one that goes from human readable numbers to regular numbers, and conversely one that would go from regular numbers to readable.

Number::Format comes close, but it doesn't grok the 'G' suffix (and actually understands only K/M instead of Kb and Mb, although I can deal with that).

Is there any module that I have overlooked that could help me? Or do I need to patch Number::Format (there is a patch in the module's RT queue), which I'd rather avoid (the module on the production machine might one day be upgraded from CPAN and the patch potentially lost).

Replies are listed 'Best First'.
Re: Module for file size arithmetic
by repellent (Priest) on Mar 12, 2009 at 12:41 UTC
    Maybe this will help. Since then, I have wrapped it up in a module:
Re: Module for file size arithmetic
by rinceWind (Monsignor) on Mar 12, 2009 at 10:16 UTC

    It's probably a sledge hammer to crack a nut, but take a look at Data::Dimensions, which could probably also handle sizes in sectors, tracks and the like, given the parameters for the disk geometry.

      My first test gets me a segmentation fault, so I'm not sure...

      perl -M'Data::Dimensions qw(:extended &units)' -E'say add( "1.2G", "50 +0M"); \ sub add \ { my $sum= units( { byte => 0 }); \ foreach (@_) { $sum += $_ } \ return $sum; \ }\ '
Re: Module for file size arithmetic
by Marshall (Canon) on Mar 12, 2009 at 11:54 UTC
    I would say first of all that your idea of 1 Gb is probably wrong? I presume that you meant 1 GB. The little b means bit, but capital B means byte.

    Oooh, this is really complex when dealing with hard disk or memory sizes. One Kilo Byte to an engineer is 1024 bytes. To a marketing guy one KB is 1,000. They do this so that the numbers look bigger!

    In "C", I would just use 64 bit int's (or unsigned 64 bit ints) for the vars which use the actual number of bytes for math operations.

    So one question that I don't know: can a perl var be assigned to 64 bit precision? If so, then this becomes easier as scaling factors aren't needed. If not then we can do this with 32 bit math.

      You're right about the B/b, the original data is in KB/MB/GB (it's awstats data).

      Beyond that, I don't really care about precision. Actually I _really_ don't care about precision, I just want to aggregate results from several sites, and get a ballpark figure, in a readable form, so with 1 or 2 digit precision. So the 1024/1000 thingie is really not a problem in that case (awstats uses 1024, like a good citizen BTW).

      It's not that complicated to do it myself, I guess I just expected CPAN to provide it.

        WOW! We've got some "industrial strength" stuff in other posts! I just hacked out something fairly "stupid" that does "MB math". So this is the "dumb" version!
        #!usr/bin/perl -w use strict; my %scale= (MB => 1, GB => 1000, KB => 0.001); sub scale2MB { my $string = shift; $string =~ tr/a-z/A-Z/; if ($string =~ /^[\d.]+$/){return $string}; my ($num,$suffix) = ($string =~ /^([\d.]+)\s*(\w+)/); return ($num * $scale{$suffix}); } foreach ("10", "10.5", "10 GB", "1kb", "10.1 GB") { print "$_=",scale2MB($_),"\n"; } my $val = scale2MB("753mb") + scale2MB("50 kb"); print "753MB+50KB is: $val\n"; __END__ prints 10=10 10.5=10.5 10 GB=10000 1kb=0.001 10.1 GB=10100 753MB+50KB is: 753.05
Re: Module for file size arithmetic
by simcop2387 (Acolyte) on Mar 15, 2009 at 03:41 UTC

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://750114]
Approved by rinceWind
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (4)
As of 2022-05-25 07:34 GMT
Find Nodes?
    Voting Booth?
    Do you prefer to work remotely?

    Results (85 votes). Check out past polls.