in reply to (tye)Re: The Definitive Unit Conversion Script
in thread The Definitive Unit Conversion Script

Actually, I am looking for a good (read: high precision values) comprehensive table of units and conversion factors to add to this. Before I add new units however I need to add a filter that rejects converted values if they get too large (ie if I ask for 1500 miles I don't want to know how much that is in milimeters).

But that's on the wishlist - for now, I needed to scratch an itch, and most every unit conversion CGI page I found out there was at least mildly painful. The too large filter is actually a bit more complex than the nobrainer too small filter. I'll update the script and add more many units when I have a few spare brain cycles (time is plentiful, but my mind is always elsewhere :-) ).

Makeshifts last the longest.

  • Comment on Re^2: The Definitive Unit Conversion Script

Replies are listed 'Best First'.
(tye)Re2: The Definitive Unit Conversion Script
by tye (Sage) on Dec 13, 2002 at 19:26 UTC

    You don't need to add a conversion factor for what I gave (though supporting such to increase precision is fine). You already handle going from 'f' to 'k' via f=>c then c=>k. It'd be nice (with a name including "Definitive") to also handle conversions between m^3 and ft^3, ft/sec and mi/hour, kg/m^2 and lb/ft^2, etc. using the data you already have in your code (except you don't have 60sec=min, 60min=hr, and ft..mi yet).

            - tye

      "Definitive" in the sense that it effortlessly converts into all related units, not in the amount of units handled. :)

      Of course it would be nice to add some limited parsing and intrinsic "understanding" of units and I can see how I'd go about implementing the basic idea (split into numerator and denominator, convert, divide), but how complex a unit specification should it be able to handle? I don't want to add so much weight that it turns into a small expression evaluator. I'm thinking one unit in the numerator, one in the denominator, and one power given for each sounds like a viably complex, sufficiently flexible spec.

      Makeshifts last the longest.

        This doesn't have to be complicated. Split on * and before /, then check for /\^\d+$/:

        my @units= split m#(?<=.)(?:(?=/)|\*)#, $units, -1; my %power; for my $unit ( @units ) { my $power= 1; if( $unit =~ s#\^(\d+)$## ) { $power= $1; } if( $unit =~ s#^/## ) { $power= -$power; } $power{$unit} += $power; } # ...
        then you have to find units that you can convert to with matching powers. So, if you start with kg/cm/sec [ which becomes (kg=>1,cm=>-1,sec=>-1) ] and are asked to return lb/ft/hr (lb=>1,ft=>-1,hr=>-1), then you have to convert from kg to lb, then convert cm to either ft or hr (there will be no cm-to-hr path so you'll do cm-to-ft), then convert the left-overs, sec-to-hr. And you're done.

        (Updated and tested.)

                - tye