All Downloads are FREE. Search and download functionalities are using the official Maven repository.

psiprobe.tools.SizeExpression Maven / Gradle / Ivy

The newest version!
/*
 * Licensed under the GPL License. You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 *
 * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
 * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */
package psiprobe.tools;

import java.text.NumberFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Tool for parsing and formatting SI-prefixed numbers in base-2 and base-10.
 */
public final class SizeExpression {

  /** The Constant MULTIPLIER_2. */
  public static final long MULTIPLIER_2 = 1024;

  /** The Constant MULTIPLIER_10. */
  public static final long MULTIPLIER_10 = 1000;

  /** The Constant UNIT_BASE. */
  public static final String UNIT_BASE = "B";

  /** The Constant PREFIX_KILO. */
  public static final char PREFIX_KILO = 'K';

  /** The Constant PREFIX_MEGA. */
  public static final char PREFIX_MEGA = 'M';

  /** The Constant PREFIX_GIGA. */
  public static final char PREFIX_GIGA = 'G';

  /** The Constant PREFIX_TERA. */
  public static final char PREFIX_TERA = 'T';

  /** The Constant PREFIX_PETA. */
  public static final char PREFIX_PETA = 'P';

  /**
   * Prevent Instantiation.
   */
  private SizeExpression() {
    // Prevent Instantiation
  }

  /**
   * Parses the given expression into a numerical value.
   *
   * 

* An expression has three parts: *

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Size Summary Table
NameDescription
Base Number(Required) The mantissa or significand of the expression. This can include decimal * values.
Prefix(Optional) The SI * prefix. These span from K for kilo- to P for peta-.
Unit(Optional) If the unit "B" (for bytes) is provided, the prefix is treated as base-2 (1024). * Otherwise, it uses base-10 (1000).
Note: Whitespace may or may not exist between the Base Number and * Prefix.
* *

* Examples: *

*
    *
  • "2k" returns {@code 2000}
  • *
  • "3.5m" returns {@code 3500000}
  • *
  • "2kb" returns {@code 2048}
  • *
  • "3.5mb" returns {@code 3670016}
  • *
* * @param expression the expression to parse * * @return the parsed value * * @throws NumberFormatException if the given expression cannot be parsed */ public static long parse(String expression) { String prefixClass = "[" + PREFIX_KILO + PREFIX_MEGA + PREFIX_GIGA + PREFIX_TERA + PREFIX_PETA + "]"; Pattern expPattern = Pattern.compile("(\\d+|\\d*\\.\\d+)\\s*(" + prefixClass + ")?(" + UNIT_BASE + ")?", Pattern.CASE_INSENSITIVE); Matcher expMatcher = expPattern.matcher(expression); if (expMatcher.matches()) { String value = expMatcher.group(1); String unitPrefix = expMatcher.group(2); String unitBase = expMatcher.group(3); double multiplier = 1; if (unitPrefix != null) { multiplier = multiplier(unitPrefix.charAt(0), unitBase != null); } double rawValue = Double.parseDouble(value); return (long) (rawValue * multiplier); } throw new NumberFormatException("Invalid expression format: " + expression); } /** * Formats the value as an expression. * * @param value the numerical value to be formatted * @param decimalPlaces the number of decimal places in the mantissa * @param base2 whether to use the base-2 (1024) multiplier and format with "B" units. If false, * uses the base-10 (1000) multiplier and no units. * * @return a formatted string expression of the value */ public static String format(long value, int decimalPlaces, boolean base2) { NumberFormat nf = NumberFormat.getInstance(); nf.setMinimumFractionDigits(decimalPlaces); double doubleResult; String unit = base2 ? UNIT_BASE : ""; double multiplierKilo = multiplier(PREFIX_KILO, base2); double multiplierMega = multiplier(PREFIX_MEGA, base2); double multiplierGiga = multiplier(PREFIX_GIGA, base2); double multiplierTera = multiplier(PREFIX_TERA, base2); double multiplierPeta = multiplier(PREFIX_PETA, base2); if (value < multiplierKilo) { doubleResult = value; nf.setMinimumFractionDigits(0); } else if (value < multiplierMega) { doubleResult = round(value / multiplierKilo, decimalPlaces); unit = PREFIX_KILO + unit; } else if (value < multiplierGiga) { doubleResult = round(value / multiplierMega, decimalPlaces); unit = PREFIX_MEGA + unit; } else if (value < multiplierTera) { doubleResult = round(value / multiplierGiga, decimalPlaces); unit = PREFIX_GIGA + unit; } else if (value < multiplierPeta) { doubleResult = round(value / multiplierTera, decimalPlaces); unit = PREFIX_TERA + unit; } else { doubleResult = round(value / multiplierPeta, decimalPlaces); unit = PREFIX_PETA + unit; } return nf.format(doubleResult) + (base2 ? " " : "") + unit; } /** * Rounds a decimal value to the given decimal place. * * @param value the value to round * @param decimalPlaces the number of decimal places to preserve. * * @return the rounded value */ private static double round(double value, int decimalPlaces) { return Math.round(value * Math.pow(10, decimalPlaces)) / Math.pow(10, decimalPlaces); } /** * Returns the base-2 or base-10 multiplier for a given prefix. * * @param unitPrefix the character representing the prefix. Can be K, M, G, T, or P. * @param base2 whether to use the base-2 (1024) multiplier. If false, uses the base-10 (1000) * multiplier. * * @return the multiplier for the given prefix */ private static double multiplier(char unitPrefix, boolean base2) { long result; long multiplier = base2 ? MULTIPLIER_2 : MULTIPLIER_10; switch (Character.toUpperCase(unitPrefix)) { case PREFIX_KILO: result = multiplier; break; case PREFIX_MEGA: result = multiplier * multiplier; break; case PREFIX_GIGA: result = multiplier * multiplier * multiplier; break; case PREFIX_TERA: result = multiplier * multiplier * multiplier * multiplier; break; case PREFIX_PETA: result = multiplier * multiplier * multiplier * multiplier * multiplier; break; default: throw new IllegalArgumentException("Invalid unit prefix: " + unitPrefix); } return result; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy