0

I can't seem to find/remember a specific formula to convert units of volume to units of mass. I think it has to do with density, but how would this be done?

In my case, I'm trying to write a program using the JScience library to convert any type of unit the user might input into the standard SI.GRAM unit.

The problem comes in with trying to describe things like honey, which are commonly measure in gallons, grams, pounds, and ounces.

I have the following code mostly working when working with units of mass, but I get a ConversionException when trying to work with gallons, which is understandable, since it's measuring volume and not mass.

javax.measure.converter.ConversionException: gal is not compatible with g

Here's what I've got so far. Also, I chose to break up the Amount<Mass> into amount_value and amount_unit because I want to store this in an SQLite database and also have it be represented as text, so I am storing it like this for serialization purposes.

public class Sugar {

    private String type;
    private double amount_value;
    private String amount_unit;


    public Sugar(SUGAR_TYPES type, Amount<Mass> amount) {
        this.type = type.toString();
        this.amount_value = amount.getEstimatedValue();
        this.amount_unit = amount.getUnit().toString();
    }    

    public Amount<Mass> getAmount() {
        BaseUnit<Mass> mass_unit = new BaseUnit<>(amount_unit);
        return Amount.valueOf(amount_value, mass_unit);     
    }

    public SUGAR_TYPES getType() {
         return (type != null) ? SUGAR_TYPES.valueOf(type) : null;
    }

    public double getAmountInGrams() {
        Amount<Mass> mass_unit = getAmount();
        switch (mass_unit.getUnit().toString().toLowerCase()) {
            case "g":
                return mass_unit.getEstimatedValue();
            case "gal":
                // this throws the ConversionException
                return NonSI.GALLON_LIQUID_US.getConverterTo(SI.GRAM).convert(mass_unit.getEstimatedValue());
            case "lb":
                return NonSI.POUND.getConverterTo(SI.GRAM).convert(mass_unit.getEstimatedValue());
            default:
                Log.e(TAG, String.format("Failed to get Amount<Mass> in SI.GRAM for amount %s and unit %s.",
                        amount_value, amount_unit));
                throw new IllegalArgumentException(mass_unit.getUnit().toString());
        }
    }

    public enum SUGAR_TYPES {
        HONEY, SUCROSE, APPLES, APRICOTS, APRICOTS_DRIED, BANANAS, BLACKBERRY, BLUEBERRY,
        BOYSENBERRY, CANTALOUPE, CELERY, CHERRY_DARK_SWEET, CRANBERRY, CURRANT_BLACK, DATES, 
        DATES_DRIED, DEWBERRY, ELDERBERRY, FIGS, FIGS_DRIED, GOOSEBERRY, GRAPE_CONCORD,
        GRAPES, GRAPEFRUIT, GUANABANA, GUAVAS, HONEYDEW_MELON, JACKFRUIT, KIWIS, LEMON_JUICE,
        LITCHI, LOGANBERRY, MANGOS, MAPLE_SYRUP, PLUMS, RAISINS_DRIED, RASPBERRY_BLACK,
        RASPBERRY_RED, RHUBARB, STRAWBERRY, TANGERINES, WATERMELONS
    }
}

Is there a better way of doing this? I have other classes that need to have a similar way of converting a generic unit into the SI unit.

Kyle Falconer
  • 8,302
  • 6
  • 48
  • 68
  • 1
    `density = mass / volume`. If you can't remember that, think of the unit: `kg/m^3` - literally, mass over volume. – Andy Turner Apr 18 '17 at 22:17
  • Right, but is there a nice/standard way to do this with common items like honey and fruit juice, besides having a lookup table of densities and doing the conversion myself? – Kyle Falconer Apr 18 '17 at 22:19
  • 1
    The definition of volume and mass _requires_ that you know the density of the _particular material._ If you want to avoid a lookup table, you will need to live in a different reality. – Louis Wasserman Apr 18 '17 at 22:21
  • Well, 1 cm^3 of water is 1 gram. – Elliott Frisch Apr 18 '17 at 22:22
  • 1
    Well thanks guys, really can't believe I forgot the formula for volume, and I guess I just have to make that density lookup table to do this right. – Kyle Falconer Apr 18 '17 at 22:25

1 Answers1

0

You will need mass per volume values for everything you want to calculate. For example, you could expand your enum to include a gram per litre (or kg per m^3, whatever works best for you). You cannot just convert volume to weight without this information:

Example: 1 litre of water=1kg, but 1 litre of petrol=0.88 kg.

Then you only need to convert input volume to your default volume, look up the type, multiply the converted volume with your saved gram per litre and return the result.

ptstone
  • 478
  • 7
  • 17