UnitsConversionUtil { public static long convert(String fromUnit, String toUnit, long fromValue) { if (toUnit == null || fromUnit == null) { throw new IllegalArgumentException("One or more arguments are null"); } if (fromUnit.equals(toUnit)) { return fromValue; } Converter fc = getConverter(fromUnit); Converter tc = getConverter(toUnit); long numerator = fc.numerator * tc.denominator; long denominator = fc.denominator * tc.numerator; long numeratorMultiplierLimit = Long.MAX_VALUE / numerator; if (numerator < denominator) { if (numeratorMultiplierLimit < fromValue) { String overflowMsg = "Converting " + fromValue + " from '" + fromUnit + "' to '" + toUnit + "' will result in an overflow of Long"; throw new IllegalArgumentException(overflowMsg); } return (fromValue * numerator) / denominator; } if (numeratorMultiplierLimit > fromValue) { return (numerator * fromValue) / denominator; } long tmp = numerator / denominator; if ((Long.MAX_VALUE / tmp) < fromValue) { String overflowMsg = "Converting " + fromValue + " from '" + fromUnit + "' to '" + toUnit + "' will result in an overflow of Long"; throw new IllegalArgumentException(overflowMsg); } return fromValue * tmp; }  static long convert(String fromUnit, String toUnit, long fromValue); static int compare(String unitA, long valueA, String unitB,
      long valueB); static int compareUnits(String unitA, String unitB); static final Set<String> KNOWN_UNITS; }
@Test public void testUnitsConversion() { int value = 5; String fromUnit = ""; long test = value; Assert.assertEquals("pico test failed", value * 1000L * 1000L * 1000L * 1000L, UnitsConversionUtil.convert(fromUnit, "p", test)); Assert.assertEquals("nano test failed", value * 1000L * 1000L * 1000L, UnitsConversionUtil.convert(fromUnit, "n", test)); Assert .assertEquals("micro test failed", value * 1000L * 1000L, UnitsConversionUtil.convert(fromUnit, "u", test)); Assert.assertEquals("milli test failed", value * 1000L, UnitsConversionUtil.convert(fromUnit, "m", test)); test = value * 1000L * 1000L * 1000L * 1000L * 1000L; fromUnit = ""; Assert.assertEquals("kilo test failed", test / 1000L, UnitsConversionUtil.convert(fromUnit, "k", test)); Assert .assertEquals("mega test failed", test / (1000L * 1000L), UnitsConversionUtil.convert(fromUnit, "M", test)); Assert.assertEquals("giga test failed", test / (1000L * 1000L * 1000L), UnitsConversionUtil.convert(fromUnit, "G", test)); Assert.assertEquals("tera test failed", test / (1000L * 1000L * 1000L * 1000L), UnitsConversionUtil.convert(fromUnit, "T", test)); Assert.assertEquals("peta test failed", test / (1000L * 1000L * 1000L * 1000L * 1000L), UnitsConversionUtil.convert(fromUnit, "P", test)); Assert.assertEquals("nano to pico test failed", value * 1000L, UnitsConversionUtil.convert("n", "p", value)); Assert.assertEquals("mega to giga test failed", value, UnitsConversionUtil.convert("M", "G", value * 1000L)); Assert.assertEquals("Mi to Gi test failed", value, UnitsConversionUtil.convert("Mi", "Gi", value * 1024L)); Assert.assertEquals("Mi to Ki test failed", value * 1024, UnitsConversionUtil.convert("Mi", "Ki", value)); Assert.assertEquals("Ki to base units test failed", 5 * 1024, UnitsConversionUtil.convert("Ki", "", 5)); Assert.assertEquals("Mi to k test failed", 1073741, UnitsConversionUtil.convert("Mi", "k", 1024)); Assert.assertEquals("M to Mi test failed", 953, UnitsConversionUtil.convert("M", "Mi", 1000)); }
@Test public void testOverflow() { long test = 5 * 1000L * 1000L * 1000L * 1000L * 1000L; try { UnitsConversionUtil.convert("P", "p", test); Assert.fail("this operation should result in an overflow"); } catch (IllegalArgumentException ie) { } try { UnitsConversionUtil.convert("m", "p", Long.MAX_VALUE - 1); Assert.fail("this operation should result in an overflow"); } catch (IllegalArgumentException ie) { } }