in reply to The Definitive Unit Conversion Script

I was interested in tye's quip about dealing with unit specifications such as 'kg/m/m' vs 'kg/m^2' I started digging around on CPAN for tokenizers that might assist in normalizing unit representations. There's some infix/postfix stuff, as well as various tokenizers such as Math::Expr that might be of assistance here.

Perhaps more importantly, there's some unit conversion modules already out there that might bear further scrutiny:


Of these, the Convert-Units bundle seems to be on the money, since in the author's words:

It is intentionally distinct from the Math::Units module. Why? The Math::Units module implies that unit conversions are exact, with one-to-one relationships. This is fine for scientific work. It's even fine for some general purpose/real-world uses (such as converting Fehrenheight to Celcius).

Real-world measurement systems are conflicting. For instance, a "point" in typography is equivalent to 1/72 inch, according to PostScript specs and common usage. Other type systems consider it 1/72.27 inch, or 0.01383 inches, or 0.0148 inches. Outside of that context, a point may be 1/120 or 1/144 inch.

Common notations and abbreviations also depend on context. Does "12 pt" mean "12 point", "12 parts" or "12 pints"?

Even without conflicts in the definition of a particular unit, there's no need to convert point sizes for fonts into miles or light-years. Typesetters, surveyors and astronomers user different scales as well as systems.

Hope these are of assistance. At the very least, you can mine the modules for conversion tables!


  • Comment on Re: The Definitive Unit Conversion Script

Replies are listed 'Best First'.
Re^2: The Definitive Unit Conversion Script
by Aristotle (Chancellor) on Dec 13, 2002 at 20:37 UTC

    Thanks for doing my digging work for me. :-) These were all quite interesting finds. Neither seems to aim for what I do.

    Math::Calc::Units and Convert::Units both attempt to offer extremly generic parsing of input and to produce human readable output to the extend of taking (in Math::Calc::Units) specifications such as 10MB / 384kbps and returning a result expressed in minutes. That's far more work than I ever intend to do, and IMHO should be done in separate stages (and therefor modules) - one to calculate a straight result, on to apply a set of heuristics to convert a given value into a more human readable specification. The latter kind of module would be useful in different environments as well.

    Math::Units is much closer to my goals, so I took a closer look. I found it only does one-shot conversions. To do so it expends considerable effort to deduce the shortest path between two indirectly convertible units. Trying to do broadside conversions with that module would be costly, and since it provides no querying interface, also quite an annoyance.

    In contrast, even though brute force, the "flood fill" approach I used naturally takes shortest path between two indirectly related units. It also does broadside conversions at no extra cost.

    My final gripe with Math::Units is that its internal data structure layout is quite complex and opaque. It doesn't look as though adding conversions is anywhere as simple as doing so in the table setup I used. Granted the module does try to be a lot more intelligent than my code, but it does lead to signficant complexity.

    Makeshifts last the longest.