using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
/// <summary>
/// Class to convert/manage units of information.
/// https://en.wikipedia.org/wiki/Units_of_information
/// </summary>
public static class DataUnitConvert {
public static double Measurement = DataUnitMeasurement.Decimal;
/// <summary>
/// Converts data from one unit of information to another to another.
/// </summary>
public static double UnitConvert(this double input, DataUnit originalType, DataUnit outputType) {
if (originalType == DataUnit.None || outputType == DataUnit.None)
return double.NaN;
double difference = Math.Abs(outputType - originalType);
if (difference == 0)
return input;
double multiplicative = Math.Pow(Measurement, difference);
if (difference > 0) // divide
return input / multiplicative;
if (difference < 0) // multiply
return input * multiplicative;
return double.NaN;
}
/// <summary>
/// Gets the best unit of information to display data in.
/// </summary>
public static DataUnit GetDataUnit(this double input, DataUnit type = DataUnit.Byte) {
DataUnit unit = DataUnit.Byte;
while (true) {
double test = input.UnitConvert(type, unit);
if (test > Measurement)
unit++;
else
break;
}
return unit;
}
/// <summary>
/// Converts input to a string, appending the specified units abbreviaton.
/// Will also round the nubmer for cleaner display.
/// </summary>
public static string ToString(this double input, DataUnit unit, int decimalPoints = 2) {
string abbr = unit.GetAbbreviation().ToUpper();
decimal dec = Convert.ToDecimal(input);
dec = decimal.Round(dec, decimalPoints, MidpointRounding.AwayFromZero);
if (unit == DataUnit.None)
return Convert.ToString(dec);
else
return Convert.ToString(dec) + " " + abbr;
}
/// <summary>
/// Converts a string to it's original data.
/// Specifying 'unit' will convert it to another unit of information automatically.
/// </summary>
public static double ToDouble(this string input, DataUnit unit = DataUnit.None) {
string[] pieces = input.Split(new[] { ' ' });
double number = Convert.ToDouble(pieces[0]);
DataUnit originalUnit = GetDataUnit(pieces[1]);
if (unit == DataUnit.None)
return number;
else
return number.UnitConvert(originalUnit, unit);
}
/// <summary>
/// Returns an abbreviation of a specified DataUnit.
/// </summary>
public static string GetAbbreviation(this DataUnit unit) {
switch (unit) {
case DataUnit.Byte: return "b";
case DataUnit.Kilobyte: return "kb";
case DataUnit.Megabyte: return "mb";
case DataUnit.Gigabyte: return "gb";
case DataUnit.Terabyte: return "tb";
case DataUnit.Petabyte: return "pb";
case DataUnit.Exabyte: return "eb";
case DataUnit.Zettabyte: return "zb";
case DataUnit.Yottabyte: return "yb";
}
return string.Empty;
}
/// <summary>
/// Returns a DataUnit based on the specified abbreviation.
/// </summary>
public static DataUnit GetDataUnit(this string unit) {
switch (unit.ToLower()) {
case "b": return DataUnit.Byte;
case "kb": return DataUnit.Kilobyte;
case "mb": return DataUnit.Megabyte;
case "gb": return DataUnit.Gigabyte;
case "tb": return DataUnit.Terabyte;
case "pb": return DataUnit.Petabyte;
case "eb": return DataUnit.Exabyte;
case "zb": return DataUnit.Zettabyte;
case "yb": return DataUnit.Yottabyte;
}
return DataUnit.None;
}
// === CONVERTED FUNCTION ===
/// <summary>
/// Converts data from one unit of information to another to another.
/// </summary>
public static double UnitConvert(this long input, DataUnit originalType, DataUnit outputType) {
double converted = Convert.ToDouble(input);
return converted.UnitConvert(originalType, outputType);
}
/// <summary>
/// Gets the best unit of information to display data in.
/// </summary>
public static DataUnit GetDataUnit(this long bytes) {
double converted = Convert.ToDouble(bytes);
return converted.GetDataUnit();
}
}
/// <summary>
/// List of supported units of information.
/// In order, least to greatest.
/// </summary>
public enum DataUnit {
None,
Byte,
Kilobyte,
Megabyte,
Gigabyte,
Terabyte,
Petabyte,
Exabyte,
Zettabyte,
Yottabyte
}
/// <summary>
/// Measurements to convert data.
/// Note: Decimal is more common, and should be used for displaying data.
/// </summary>
public struct DataUnitMeasurement {
public const double Binary = 1024.0;
public const double Decimal = 1000.0;
}
Comments