Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# data structure for multiple unit conversions

I have a C# app and I need to convert between 3 different units (say for example: litres, gallons, and pints).

The app needs to know about certain volumes of liquid, say: 1 pint, 10 pints, 20 pints and 100 pints. I intend to do the calculations and hard code the values (not ideal but necessary),

I'm looking for a data structure that will allow me to easily convert from one unit to another.

Any suggestions?

Please note: I'm not actually using volumes of liquid, its just an example!

like image 435
TK. Avatar asked Dec 06 '22 07:12

TK.


2 Answers

You can store a matrix of conversion factors where

  • a: Is litres
  • b: Is pints
  • c: Are gallons

You'd have (not accurate, but assuming there are two pints to a litre and 4 litres to a gallon)

   a     b       c
a  1     2     0.25
b  0.5   1     0.125
c  4     8       1

Alternatively, you can decide that everything is converted to a base value (litres) before being converted to another type, then you just need the first line.

Wrap this in a method that takes a number of units and "from" type and "two" type for the conversion.

Hope this helps

EDIT: some code, as requested

    public enum VolumeType
    {
        Litre = 0,
        Pint = 1,
        Gallon = 2
    }

    public static double ConvertUnits(int units, VolumeType from, VolumeType to)
    {
        double[][] factor = 
            {
                new double[] {1, 2, 0.25},
                new double[] {0.5, 1, 0.125},
                new double[] {4, 8, 1}
            };
        return units * factor[(int)from][(int)to];
    }

    public static void ShowConversion(int oldUnits, VolumeType from, VolumeType to)
    {
        double newUnits = ConvertUnits(oldUnits, from, to);
        Console.WriteLine("{0} {1} = {2} {3}", oldUnits, from.ToString(), newUnits, to.ToString());
    }


    static void Main(string[] args)
    {
        ShowConversion(1, VolumeType.Litre, VolumeType.Litre);  // = 1
        ShowConversion(1, VolumeType.Litre, VolumeType.Pint);   // = 2
        ShowConversion(1, VolumeType.Litre, VolumeType.Gallon); // = 4
        ShowConversion(1, VolumeType.Pint, VolumeType.Pint);    // = 1
        ShowConversion(1, VolumeType.Pint, VolumeType.Litre);   // = 0.5
        ShowConversion(1, VolumeType.Pint, VolumeType.Gallon);  // = 0.125
        ShowConversion(1, VolumeType.Gallon, VolumeType.Gallon);// = 1
        ShowConversion(1, VolumeType.Gallon, VolumeType.Pint);  // = 8
        ShowConversion(1, VolumeType.Gallon, VolumeType.Litre); // = 4
        ShowConversion(10, VolumeType.Litre, VolumeType.Pint);  // = 20
        ShowConversion(20, VolumeType.Gallon, VolumeType.Pint); // = 160
    }
like image 155
Binary Worrier Avatar answered Dec 07 '22 20:12

Binary Worrier


I have done this in an other language by providing the correct access methods (properties):

for the class Volume:
  AsLitre
  AsGallon
  AsPint

for the class Distance:
  AsInch
  AsMeter
  AsYard
  AsMile

One additional advantage is that the internal format does not matter.

like image 35
Toon Krijthe Avatar answered Dec 07 '22 19:12

Toon Krijthe