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 void testUnitsConversion() { int value = 5; String fromUnit = ""; long test = value; assertEquals(value * 1000L * 1000L * 1000L * 1000L, UnitsConversionUtil.convert(fromUnit, "p", test), "pico test failed"); assertEquals(value * 1000L * 1000L * 1000L, UnitsConversionUtil.convert(fromUnit, "n", test), "nano test failed"); assertEquals(value * 1000L * 1000L, UnitsConversionUtil.convert(fromUnit, "u", test), "micro test failed"); assertEquals(value * 1000L, UnitsConversionUtil.convert(fromUnit, "m", test), "milli test failed"); test = value * 1000L * 1000L * 1000L * 1000L * 1000L; fromUnit = ""; assertEquals(test / 1000L, UnitsConversionUtil.convert(fromUnit, "k", test), "kilo test failed"); assertEquals(test / (1000L * 1000L), UnitsConversionUtil.convert(fromUnit, "M", test), "mega test failed"); assertEquals(test / (1000L * 1000L * 1000L), UnitsConversionUtil.convert(fromUnit, "G", test), "giga test failed"); assertEquals(test / (1000L * 1000L * 1000L * 1000L), UnitsConversionUtil.convert(fromUnit, "T", test), "tera test failed"); assertEquals(test / (1000L * 1000L * 1000L * 1000L * 1000L), UnitsConversionUtil.convert(fromUnit, "P", test), "peta test failed"); assertEquals(value * 1000L, UnitsConversionUtil.convert("n", "p", value), "nano to pico test failed"); assertEquals(value, UnitsConversionUtil.convert("M", "G", value * 1000L), "mega to giga test failed"); assertEquals(value, UnitsConversionUtil.convert("Mi", "Gi", value * 1024L), "Mi to Gi test failed"); assertEquals(value * 1024, UnitsConversionUtil.convert("Mi", "Ki", value), "Mi to Ki test failed"); assertEquals(5 * 1024, UnitsConversionUtil.convert("Ki", "", 5), "Ki to base units test failed"); assertEquals(1073741, UnitsConversionUtil.convert("Mi", "k", 1024), "Mi to k test failed"); assertEquals(953, UnitsConversionUtil.convert("M", "Mi", 1000), "M to Mi test failed"); }
@Test void testOverflow() { long test = 5 * 1000L * 1000L * 1000L * 1000L * 1000L; try { UnitsConversionUtil.convert("P", "p", test); fail("this operation should result in an overflow"); } catch (IllegalArgumentException ie) { } try { UnitsConversionUtil.convert("m", "p", Long.MAX_VALUE - 1); fail("this operation should result in an overflow"); } catch (IllegalArgumentException ie) { } }