Thread: ideas for a generalized unit-handling class

  1. #1
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838

    ideas for a generalized unit-handling class

    it would be wonderful if i could implement a generalized unit class, but as simple of a concept as it is, a good way to implement it eludes me...

    here's what i have so far, obviously it's clumsy and woefully inadequate, but at least it's a starting point for some discussion.

    Code:
    class unit
    {
            public:
            unit(size_t NumUnits) : numUnits(NumUnits){} 
            double exponent;
            double coeff;
            const  size_t numUnits;
            unit *units;
            double convert(unit u)
            {
                    //returns a conversion factor if this and u are of compatible dimensions
            };
            unit multiply(unit u)
            {
                    //adds exponents of this->units of this and u->units
            }
            unit divide(unit u)
            {
                    //subtracts exponents of this->units of and u->units
            }
    };
    there has got to be a more elegant and robust way of doing this. any suggestions (including 3rd party wares) would be greatly appreciated.

  2. #2
    Registered User
    Join Date
    Apr 2008
    Posts
    890
    You're talking about units of measurement, I assume? First question is how would clients of the class use it? And are you talking about all units (length, volume, pressure, force, mass, etc.)?

    A class hierarchy seems to wrong way to approach this. I'd start with a set of conversion functions.

  3. #3

    Join Date
    Apr 2008
    Location
    USA
    Posts
    76
    Also, you might want to use operator overloading.

    Try something like this:

    5dam + 100cm = 51m
    Code:
    unit m = unit(5).deca_meters() + unit(100).centi_meters();
    // m.meters() == 51

  4. #4
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Boost's review queue contains two different candidates for unit libraries.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  5. #5
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    Quote Originally Posted by rudyman View Post
    Also, you might want to use operator overloading.

    Try something like this:

    5dam + 100cm = 51m
    Code:
    unit m = unit(5).deca_meters() + unit(100).centi_meters();
    // m.meters() == 51
    yes, that would be a good idea for unit prefixes d,m,c,k,etc; but otherwise, it is not particularly useful.

    i'd have to create operators for hundreds of possible permutations of units.

  6. #6
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    Quote Originally Posted by CornedBee View Post
    Boost's review queue contains two different candidates for unit libraries.
    just dl'd 1_35.07z and it doesn't appear to have been released yet, tho they say they'd added it. :\

  7. #7
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    so, what i see as the major weakness in the above class is the sorting of the array unit::units

    in order to check dimensional compatibility or perform an operation i would have to loop over the entire array numUnits times.

    Probably not too expensive, but it is a rather ugly brute force implementation...

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by m37h0d View Post
    so, what i see as the major weakness in the above class is the sorting of the array unit::units

    in order to check dimensional compatibility or perform an operation i would have to loop over the entire array numUnits times.

    Probably not too expensive, but it is a rather ugly brute force implementation...
    Instead of having conversions between each type of unit, have a "standard unit" for each type of unit (so distances are perhaps in meter, time in seconds, energy in Joule, etc).

    That way, you just need a table for each type of unit.

    To make for example speed units, then you would have a "multi_unit class", which links for example a distance unit to a time unit to produce speed (base-unit is meters per second, but you can use the conversions to make this into miles per hour (meter-> miles, seconds->hours) or inches/s, etc). This would also apply to "area" and "volume", where you would combine two or three lengths into a multi_unit.

    You'd obviously need to know if the multi-unit is multiplicative or divisive or perhaps even a combination of, e.g. liters of fuel per kilometer is obliviously a volume divided by distance [whcih can be simplified to an area measurement, but that doesn't actually make any sense whatsoever] - this would then translate to Miles per gallon, which is an distance / volume.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    yes, i use "kms" units as my algorithmic standard. having an internal standard like that is required to do a conversion at all; otherwise how do you know how many miles are in a parsec, for example.

    i often need to change the way that the quantities are displayed; e.g. displaying 1ppm instead of 0.0001 wt%.

    also, our customers in europe aren't particularly fond of "psi", whereas our U.S. customers are quite happy with that and might not be familiar with kPa.

    it would also be useful for my purposes in my calculations for checking or preventing unit-conversion errors.



    anyway, if i'm interpreting you correctly here, you're suggesting that i make a few derived classes of unit to represent the principal quantities: e.g. mass, length, time, temperature, etc.; then create a multi-unit container class that handles the conversion.

    i had considered something like this, but i am at a loss for an efficient way to perform the operations and dimensional consistency checking...

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by m37h0d View Post
    just dl'd 1_35.07z and it doesn't appear to have been released yet, tho they say they'd added it. :\
    True. It's in the SVN trunk, though, so it'll be in 1.36.0.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, one base-unit that you derive length/distance, mass, etc from.

    Also, for most intents and purposes 1mg/L is also 1ppm (although that's only valid for water, and to be very precise, only at 4 degrees Celsius).

    Which makes me realizse that temperatures (and possibly other conversions) may need an offset to convert from one to another - C to F definitely does. I think there are variants of pressure using the unit bar that are either "zero- or one-based", meaning that a total vacuum is either -1 or 0 depending on which variant of bar you use. Just to make sure you don't just use a multiplicative conversion.

    I'm sorry, but I can't (quickly) come up with a neat solution as to the best way to do conversions between units and check correctness - I suppose if you take any unit back to it's base-units, you'd be able to verify that the two base-units are the same.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Class Constructor error handling
    By cyreon in forum C++ Programming
    Replies: 8
    Last Post: 02-18-2009, 02:18 PM
  2. deriving classes
    By l2u in forum C++ Programming
    Replies: 12
    Last Post: 01-15-2007, 05:01 PM
  3. Warnings, warnings, warnings?
    By spentdome in forum C Programming
    Replies: 25
    Last Post: 05-27-2002, 06:49 PM
  4. gcc problem
    By bjdea1 in forum Linux Programming
    Replies: 13
    Last Post: 04-29-2002, 06:51 PM
  5. Difficulty superclassing EDIT window class
    By cDir in forum Windows Programming
    Replies: 7
    Last Post: 02-21-2002, 05:06 PM