From 9ba6fc1c82c4f770bc61131f082b114069fabbcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bark=C3=A5?= Date: Thu, 3 Jan 2019 00:07:12 +0100 Subject: [PATCH 01/13] Updated public API. Started implenting #526. Fixed some grammar. --- ...provalTest.approve_public_api.approved.txt | 4 +- src/Humanizer/MetricNumeralExtensions.cs | 44 +++++++++++++++---- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt index a94665fa7..02f8be867 100644 --- a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt +++ b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt @@ -412,8 +412,8 @@ namespace Humanizer public class static MetricNumeralExtensions { public static double FromMetric(this string input) { } - public static string ToMetric(this int input, bool hasSpace = False, bool useSymbol = True, System.Nullable decimals = null) { } - public static string ToMetric(this double input, bool hasSpace = False, bool useSymbol = True, System.Nullable decimals = null) { } + public static string ToMetric(this int input, bool hasSpace = False, bool useSymbol = True, System.Nullable decimals = null, System.Nullable largestPrefix = null) { } + public static string ToMetric(this double input, bool hasSpace = False, bool useSymbol = True, System.Nullable decimals = null, System.Nullable largestPrefix = null) { } } public class NoMatchFoundException : System.Exception { diff --git a/src/Humanizer/MetricNumeralExtensions.cs b/src/Humanizer/MetricNumeralExtensions.cs index 5ce9a3e2d..bb1fa37a1 100644 --- a/src/Humanizer/MetricNumeralExtensions.cs +++ b/src/Humanizer/MetricNumeralExtensions.cs @@ -101,17 +101,19 @@ public static double FromMetric(this string input) /// True will split the number and the symbol with a whitespace. /// True will use symbol instead of name /// If not null it is the numbers of decimals to round the number to + /// If not null it is the largest prefix used in result. /// /// /// 1000.ToMetric() => "1k" /// 123.ToMetric() => "123" /// 1E-1.ToMetric() => "100m" + /// 1_000_000.ToMetric(largestPrefix = 'k') => "1000k" /// /// /// A valid Metric representation - public static string ToMetric(this int input, bool hasSpace = false, bool useSymbol = true, int? decimals = null) + public static string ToMetric(this int input, bool hasSpace = false, bool useSymbol = true, int? decimals = null, char? largestPrefix = null) { - return ((double)input).ToMetric(hasSpace, useSymbol, decimals); + return ((double)input).ToMetric(hasSpace, useSymbol, decimals, largestPrefix); } /// @@ -125,15 +127,17 @@ public static string ToMetric(this int input, bool hasSpace = false, bool useSym /// True will split the number and the symbol with a whitespace. /// True will use symbol instead of name /// If not null it is the numbers of decimals to round the number to + /// If not null it is the largest prefix used in result. /// /// /// 1000d.ToMetric() => "1k" /// 123d.ToMetric() => "123" /// 1E-1.ToMetric() => "100m" + /// 1_000_000.ToMetric(largestPrefix = 'k') => "1000k" /// /// /// A valid Metric representation - public static string ToMetric(this double input, bool hasSpace = false, bool useSymbol = true, int? decimals = null) + public static string ToMetric(this double input, bool hasSpace = false, bool useSymbol = true, int? decimals = null, char? largestPrefix = null) { if (input.Equals(0)) { @@ -145,7 +149,7 @@ public static string ToMetric(this double input, bool hasSpace = false, bool use throw new ArgumentOutOfRangeException(nameof(input)); } - return BuildRepresentation(input, hasSpace, useSymbol, decimals); + return BuildRepresentation(input, hasSpace, useSymbol, decimals, largestPrefix); } /// @@ -217,13 +221,14 @@ private static string ReplaceNameBySymbol(string input) /// True will split the number and the symbol with a whitespace. /// True will use symbol instead of name /// If not null it is the numbers of decimals to round the number to + /// If not null it is the largest prefix used in result. /// A number in a Metric representation - private static string BuildRepresentation(double input, bool hasSpace, bool useSymbol, int? decimals) + private static string BuildRepresentation(double input, bool hasSpace, bool useSymbol, int? decimals, char? largestPrefix = null) { var exponent = (int)Math.Floor(Math.Log10(Math.Abs(input)) / 3); return exponent.Equals(0) ? input.ToString() - : BuildMetricRepresentation(input, exponent, hasSpace, useSymbol, decimals); + : BuildMetricRepresentation(input, exponent, hasSpace, useSymbol, decimals, largestPrefix); } /// @@ -234,9 +239,13 @@ private static string BuildRepresentation(double input, bool hasSpace, bool useS /// True will split the number and the symbol with a whitespace. /// True will use symbol instead of name /// If not null it is the numbers of decimals to round the number to + /// If not null it is the largest prefix used in result. /// A number in a Metric representation - private static string BuildMetricRepresentation(double input, int exponent, bool hasSpace, bool useSymbol, int? decimals) + private static string BuildMetricRepresentation(double input, int exponent, bool hasSpace, bool useSymbol, int? decimals, char? largestPrefix = null) { + if (largestPrefix != null) + exponent = LimitExponent(exponent, (char)largestPrefix); + var number = input * Math.Pow(1000, -exponent); if (decimals.HasValue) { @@ -251,6 +260,18 @@ private static string BuildMetricRepresentation(double input, int exponent, bool + GetUnit(symbol, useSymbol); } + // TODO docs + private static int LimitExponent(int exponent, char largestPrefix) + { + // TODO largestPrefix = largestPrefix.Trim(); When changed to string + + if (!(Symbols[0].Contains(largestPrefix) || Symbols[1].Contains(largestPrefix))) + throw new ArgumentException("Empty or invalid Metric prefix character.", nameof(largestPrefix)); // TODO change to "string". + + return exponent; // TODO + } + + /// /// Get the unit from a symbol of from the symbol's name. /// @@ -265,7 +286,7 @@ private static string GetUnit(char symbol, bool useSymbol) /// /// Check if a Metric representation is out of the valid range. /// - /// A Metric representation who might be out of the valid range. + /// A Metric representation that may be out of the valid range. /// True if input is out of the valid range. private static bool IsOutOfRange(this double input) { @@ -283,7 +304,7 @@ private static bool IsOutOfRange(this double input) /// /// ToDo: Performance: Use (string input, out number) to escape the double use of Parse() /// - /// A string who might contain a invalid Metric representation. + /// A string that may contain an invalid Metric representation. /// True if input is not a valid Metric representation. private static bool IsInvalidMetricNumeral(this string input) { @@ -292,5 +313,10 @@ private static bool IsInvalidMetricNumeral(this string input) var isSymbol = Symbols[0].Contains(last) || Symbols[1].Contains(last); return !double.TryParse(isSymbol ? input.Remove(index) : input, out var number); } + + private static bool IsInvalidMetricPrefix(this string input) + { + return false; //TODO + } } } From 6b83121465c3057aa68ee759a897d9008a1f5ac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bark=C3=A5?= Date: Thu, 3 Jan 2019 09:52:18 +0100 Subject: [PATCH 02/13] Basic implementation of #526 with tests. --- .../MetricNumeralTests.cs | 32 ++++++++++--------- src/Humanizer/MetricNumeralExtensions.cs | 18 +++++++---- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/Humanizer.Tests.Shared/MetricNumeralTests.cs b/src/Humanizer.Tests.Shared/MetricNumeralTests.cs index 252a753d2..9d719fe14 100644 --- a/src/Humanizer.Tests.Shared/MetricNumeralTests.cs +++ b/src/Humanizer.Tests.Shared/MetricNumeralTests.cs @@ -90,24 +90,26 @@ public void TestAllSymbolsAsInt(int exponent) } [Theory] - [InlineData("0", 0d, false, true, null)] - [InlineData("123", 123d, false, true, null)] - [InlineData("-123", (-123d), false, true, null)] - [InlineData("1.23k", 1230d, false, true, null)] - [InlineData("1 k", 1000d, true, true, null)] - [InlineData("1 kilo", 1000d, true, false, null)] - [InlineData("1milli", 1E-3, false, false, null)] - [InlineData("1.23milli", 1.234E-3, false, false, 2)] - [InlineData("12.34k", 12345, false, true, 2)] - [InlineData("12k", 12345, false, true, 0)] - [InlineData("-3.9m", -3.91e-3, false, true, 1)] - public void ToMetric(string expected, double input, bool hasSpace, bool useSymbol, int? decimals) + [InlineData("0", 0d, false, true, null, null)] + [InlineData("123", 123d, false, true, null, null)] + [InlineData("-123", (-123d), false, true, null, null)] + [InlineData("1.23k", 1230d, false, true, null, null)] + [InlineData("1 k", 1000d, true, true, null, null)] + [InlineData("1 kilo", 1000d, true, false, null, null)] + [InlineData("1milli", 1E-3, false, false, null, null)] + [InlineData("1.23milli", 1.234E-3, false, false, 2, null)] + [InlineData("12.34k", 12345, false, true, 2, null)] + [InlineData("12k", 12345, false, true, 0, null)] + [InlineData("-3.9m", -3.91e-3, false, true, 1, null)] + [InlineData("-3.9m", -3.91e-3, false, true, 1, 'M')] + [InlineData("10M", 10_000_000, false, true, null, 'G')] + [InlineData("10000k", 10_000_000, false, true, null, 'k')] + [InlineData("1234.56k", 1_234_560, false, true, null, 'k')] + public void ToMetric(string expected, double input, bool hasSpace, bool useSymbol, int? decimals, char? largestPrefix) { - Assert.Equal(expected, input.ToMetric(hasSpace, useSymbol, decimals)); + Assert.Equal(expected, input.ToMetric(hasSpace, useSymbol, decimals, largestPrefix)); } - - [Theory] [InlineData(1E+27)] [InlineData(1E-27)] diff --git a/src/Humanizer/MetricNumeralExtensions.cs b/src/Humanizer/MetricNumeralExtensions.cs index bb1fa37a1..34635dc13 100644 --- a/src/Humanizer/MetricNumeralExtensions.cs +++ b/src/Humanizer/MetricNumeralExtensions.cs @@ -243,24 +243,29 @@ private static string BuildRepresentation(double input, bool hasSpace, bool useS /// A number in a Metric representation private static string BuildMetricRepresentation(double input, int exponent, bool hasSpace, bool useSymbol, int? decimals, char? largestPrefix = null) { - if (largestPrefix != null) + if (largestPrefix.HasValue) exponent = LimitExponent(exponent, (char)largestPrefix); var number = input * Math.Pow(1000, -exponent); + if (decimals.HasValue) - { number = Math.Round(number, decimals.Value); - } var symbol = Math.Sign(exponent) == 1 ? Symbols[0][exponent - 1] : Symbols[1][-exponent - 1]; + return number + (hasSpace ? " " : string.Empty) + GetUnit(symbol, useSymbol); } - // TODO docs + /// + /// Limit upper size of exponent value to that corresponding to a metric prefix symbol. TODO synbol or name. + /// + /// The exponent to limit. + /// True will use symbol instead of name + /// A symbol or a symbol's name private static int LimitExponent(int exponent, char largestPrefix) { // TODO largestPrefix = largestPrefix.Trim(); When changed to string @@ -268,9 +273,10 @@ private static int LimitExponent(int exponent, char largestPrefix) if (!(Symbols[0].Contains(largestPrefix) || Symbols[1].Contains(largestPrefix))) throw new ArgumentException("Empty or invalid Metric prefix character.", nameof(largestPrefix)); // TODO change to "string". - return exponent; // TODO - } + var maxExponent = (Symbols[0].IndexOf(largestPrefix) + 1); // TODO check symbols[1] + return maxExponent < exponent ? maxExponent : exponent; + } /// /// Get the unit from a symbol of from the symbol's name. From 822a0aa3b1559fdd78f4b976569aed33ffff7da1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bark=C3=A5?= Date: Thu, 3 Jan 2019 10:45:38 +0100 Subject: [PATCH 03/13] Renamed an existing method parameter for clarity. --- src/Humanizer/MetricNumeralExtensions.cs | 31 ++++++++++-------------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/src/Humanizer/MetricNumeralExtensions.cs b/src/Humanizer/MetricNumeralExtensions.cs index 34635dc13..f35946e7c 100644 --- a/src/Humanizer/MetricNumeralExtensions.cs +++ b/src/Humanizer/MetricNumeralExtensions.cs @@ -235,25 +235,25 @@ private static string BuildRepresentation(double input, bool hasSpace, bool useS /// Build a Metric representation of the number. /// /// Number to convert to a Metric representation. - /// Exponent of the number in a scientific notation + /// Metric prefix expressed as a number. /// True will split the number and the symbol with a whitespace. /// True will use symbol instead of name /// If not null it is the numbers of decimals to round the number to /// If not null it is the largest prefix used in result. /// A number in a Metric representation - private static string BuildMetricRepresentation(double input, int exponent, bool hasSpace, bool useSymbol, int? decimals, char? largestPrefix = null) + private static string BuildMetricRepresentation(double input, int numericPrefix, bool hasSpace, bool useSymbol, int? decimals, char? largestPrefix = null) { if (largestPrefix.HasValue) - exponent = LimitExponent(exponent, (char)largestPrefix); + numericPrefix = LimitNumericPrefix(numericPrefix, (char)largestPrefix); - var number = input * Math.Pow(1000, -exponent); + var number = input * Math.Pow(1000, -numericPrefix); if (decimals.HasValue) number = Math.Round(number, decimals.Value); - var symbol = Math.Sign(exponent) == 1 - ? Symbols[0][exponent - 1] - : Symbols[1][-exponent - 1]; + var symbol = Math.Sign(numericPrefix) == 1 + ? Symbols[0][numericPrefix - 1] + : Symbols[1][-numericPrefix - 1]; return number + (hasSpace ? " " : string.Empty) @@ -261,12 +261,12 @@ private static string BuildMetricRepresentation(double input, int exponent, bool } /// - /// Limit upper size of exponent value to that corresponding to a metric prefix symbol. TODO synbol or name. + /// Limit upper size of a numeric representation of metric prefix. /// - /// The exponent to limit. - /// True will use symbol instead of name - /// A symbol or a symbol's name - private static int LimitExponent(int exponent, char largestPrefix) + /// Metric prefix, expressed as a number, to limit. + /// Metric prefix symbol of upper limit. // TODO symbol or name. + /// Upper limited numeric prefix represenation + private static int LimitNumericPrefix(int numericPrefix, char largestPrefix) { // TODO largestPrefix = largestPrefix.Trim(); When changed to string @@ -275,7 +275,7 @@ private static int LimitExponent(int exponent, char largestPrefix) var maxExponent = (Symbols[0].IndexOf(largestPrefix) + 1); // TODO check symbols[1] - return maxExponent < exponent ? maxExponent : exponent; + return maxExponent < numericPrefix ? maxExponent : numericPrefix; } /// @@ -319,10 +319,5 @@ private static bool IsInvalidMetricNumeral(this string input) var isSymbol = Symbols[0].Contains(last) || Symbols[1].Contains(last); return !double.TryParse(isSymbol ? input.Remove(index) : input, out var number); } - - private static bool IsInvalidMetricPrefix(this string input) - { - return false; //TODO - } } } From 014efec29fa2760b5f5a1098c98ccc09c6263dd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bark=C3=A5?= Date: Thu, 3 Jan 2019 12:41:09 +0100 Subject: [PATCH 04/13] Added support for fractional prefixes to largestPrefix option. --- .../MetricNumeralTests.cs | 32 ++++++++++--------- src/Humanizer/MetricNumeralExtensions.cs | 13 +++++--- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/Humanizer.Tests.Shared/MetricNumeralTests.cs b/src/Humanizer.Tests.Shared/MetricNumeralTests.cs index 9d719fe14..c88624272 100644 --- a/src/Humanizer.Tests.Shared/MetricNumeralTests.cs +++ b/src/Humanizer.Tests.Shared/MetricNumeralTests.cs @@ -90,21 +90,23 @@ public void TestAllSymbolsAsInt(int exponent) } [Theory] - [InlineData("0", 0d, false, true, null, null)] - [InlineData("123", 123d, false, true, null, null)] - [InlineData("-123", (-123d), false, true, null, null)] - [InlineData("1.23k", 1230d, false, true, null, null)] - [InlineData("1 k", 1000d, true, true, null, null)] - [InlineData("1 kilo", 1000d, true, false, null, null)] - [InlineData("1milli", 1E-3, false, false, null, null)] - [InlineData("1.23milli", 1.234E-3, false, false, 2, null)] - [InlineData("12.34k", 12345, false, true, 2, null)] - [InlineData("12k", 12345, false, true, 0, null)] - [InlineData("-3.9m", -3.91e-3, false, true, 1, null)] - [InlineData("-3.9m", -3.91e-3, false, true, 1, 'M')] - [InlineData("10M", 10_000_000, false, true, null, 'G')] - [InlineData("10000k", 10_000_000, false, true, null, 'k')] - [InlineData("1234.56k", 1_234_560, false, true, null, 'k')] + [InlineData("0", 0d, false, true, null, null)] + [InlineData("123", 123d, false, true, null, null)] + [InlineData("-123", (-123d), false, true, null, null)] + [InlineData("1.23k", 1230d, false, true, null, null)] + [InlineData("1 k", 1000d, true, true, null, null)] + [InlineData("1 kilo", 1000d, true, false, null, null)] + [InlineData("1milli", 1E-3, false, false, null, null)] + [InlineData("1.23milli", 1.234E-3, false, false, 2, null)] + [InlineData("12.34k", 12345, false, true, 2, null)] + [InlineData("12k", 12345, false, true, 0, null)] + [InlineData("-3.9m", -3.91e-3, false, true, 1, null)] + [InlineData("-3.9m", -3.91e-3, false, true, 1, 'M')] + [InlineData("1M", 1_000_000, false, true, null, 'G')] + [InlineData("1000k", 1_000_000, false, true, null, 'k')] + [InlineData("1234.56k", 1_234_560, false, true, null, 'k')] + [InlineData("1m", 1E-3, false, true, null, null)] + [InlineData("1000μ", 1E-3, false, true, null, 'μ')] public void ToMetric(string expected, double input, bool hasSpace, bool useSymbol, int? decimals, char? largestPrefix) { Assert.Equal(expected, input.ToMetric(hasSpace, useSymbol, decimals, largestPrefix)); diff --git a/src/Humanizer/MetricNumeralExtensions.cs b/src/Humanizer/MetricNumeralExtensions.cs index f35946e7c..d42ea548e 100644 --- a/src/Humanizer/MetricNumeralExtensions.cs +++ b/src/Humanizer/MetricNumeralExtensions.cs @@ -270,12 +270,17 @@ private static int LimitNumericPrefix(int numericPrefix, char largestPrefix) { // TODO largestPrefix = largestPrefix.Trim(); When changed to string - if (!(Symbols[0].Contains(largestPrefix) || Symbols[1].Contains(largestPrefix))) - throw new ArgumentException("Empty or invalid Metric prefix character.", nameof(largestPrefix)); // TODO change to "string". + int maxPrefix; + if (Symbols[0].Contains(largestPrefix)) + maxPrefix = (Symbols[0].IndexOf(largestPrefix) + 1); - var maxExponent = (Symbols[0].IndexOf(largestPrefix) + 1); // TODO check symbols[1] + else if (Symbols[1].Contains(largestPrefix)) + maxPrefix = -(Symbols[1].IndexOf(largestPrefix) + 1); - return maxExponent < numericPrefix ? maxExponent : numericPrefix; + else + throw new ArgumentException("Invalid Metric prefix character.", nameof(largestPrefix)); // TODO change to "string". + + return maxPrefix < numericPrefix ? maxPrefix : numericPrefix; } /// From e70b7053aece44a4b04e5aa85b3d79465789cfdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bark=C3=A5?= Date: Fri, 4 Jan 2019 16:26:41 +0100 Subject: [PATCH 05/13] Added enum MetricPrefix, containing all supported metric prefixes and the corresponding powers of ten as underlying values. --- ...provalTest.approve_public_api.approved.txt | 19 ++++++++++++++ src/Humanizer/MetricPrefix.cs | 26 +++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 src/Humanizer/MetricPrefix.cs diff --git a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt index 02f8be867..4fe382785 100644 --- a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt +++ b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt @@ -415,6 +415,25 @@ namespace Humanizer public static string ToMetric(this int input, bool hasSpace = False, bool useSymbol = True, System.Nullable decimals = null, System.Nullable largestPrefix = null) { } public static string ToMetric(this double input, bool hasSpace = False, bool useSymbol = True, System.Nullable decimals = null, System.Nullable largestPrefix = null) { } } + public enum MetricPrefix + { + Yocto = -24, + Zepto = -21, + Atto = -18, + Femto = -15, + Pico = -12, + Nano = -9, + Micro = -6, + Milli = -3, + Kilo = 3, + Mega = 6, + Giga = 9, + Tera = 12, + Peta = 15, + Exa = 18, + Zetta = 21, + Yotta = 24, + } public class NoMatchFoundException : System.Exception { public NoMatchFoundException() { } diff --git a/src/Humanizer/MetricPrefix.cs b/src/Humanizer/MetricPrefix.cs new file mode 100644 index 000000000..6864c530d --- /dev/null +++ b/src/Humanizer/MetricPrefix.cs @@ -0,0 +1,26 @@ +namespace Humanizer +{ + /// + /// MetricPrefix contains all supported metric prefixes and the corresponding powers of ten as underlying values. + /// Unsupported: hecto, deca, deci and centi. + /// + public enum MetricPrefix + { + Yocto = -24, + Zepto = -21, + Atto = -18, + Femto = -15, + Pico = -12, + Nano = -9, + Micro = -6, + Milli = -3, + Kilo = 3, + Mega = 6, + Giga = 9, + Tera = 12, + Peta = 15, + Exa = 18, + Zetta = 21, + Yotta = 24 + } +} From afe0ef2d4ae270f99f1771dc56f0b7a69f128ef4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bark=C3=A5?= Date: Fri, 4 Jan 2019 18:08:05 +0100 Subject: [PATCH 06/13] Added default to MetricPrefix. Updated ToMetric to use MetricPrefix. Updated tests. --- .../MetricNumeralTests.cs | 36 +++++++++---------- ...provalTest.approve_public_api.approved.txt | 5 +-- src/Humanizer/MetricNumeralExtensions.cs | 21 +++++------ src/Humanizer/MetricPrefix.cs | 3 +- 4 files changed, 34 insertions(+), 31 deletions(-) diff --git a/src/Humanizer.Tests.Shared/MetricNumeralTests.cs b/src/Humanizer.Tests.Shared/MetricNumeralTests.cs index c88624272..21f250933 100644 --- a/src/Humanizer.Tests.Shared/MetricNumeralTests.cs +++ b/src/Humanizer.Tests.Shared/MetricNumeralTests.cs @@ -90,24 +90,24 @@ public void TestAllSymbolsAsInt(int exponent) } [Theory] - [InlineData("0", 0d, false, true, null, null)] - [InlineData("123", 123d, false, true, null, null)] - [InlineData("-123", (-123d), false, true, null, null)] - [InlineData("1.23k", 1230d, false, true, null, null)] - [InlineData("1 k", 1000d, true, true, null, null)] - [InlineData("1 kilo", 1000d, true, false, null, null)] - [InlineData("1milli", 1E-3, false, false, null, null)] - [InlineData("1.23milli", 1.234E-3, false, false, 2, null)] - [InlineData("12.34k", 12345, false, true, 2, null)] - [InlineData("12k", 12345, false, true, 0, null)] - [InlineData("-3.9m", -3.91e-3, false, true, 1, null)] - [InlineData("-3.9m", -3.91e-3, false, true, 1, 'M')] - [InlineData("1M", 1_000_000, false, true, null, 'G')] - [InlineData("1000k", 1_000_000, false, true, null, 'k')] - [InlineData("1234.56k", 1_234_560, false, true, null, 'k')] - [InlineData("1m", 1E-3, false, true, null, null)] - [InlineData("1000μ", 1E-3, false, true, null, 'μ')] - public void ToMetric(string expected, double input, bool hasSpace, bool useSymbol, int? decimals, char? largestPrefix) + [InlineData("0", 0d, false, true, null, MetricPrefix.None)] + [InlineData("123", 123d, false, true, null, MetricPrefix.None)] + [InlineData("-123", (-123d), false, true, null, MetricPrefix.None)] + [InlineData("1.23k", 1230d, false, true, null, MetricPrefix.None)] + [InlineData("1 k", 1000d, true, true, null, MetricPrefix.None)] + [InlineData("1 kilo", 1000d, true, false, null, MetricPrefix.None)] + [InlineData("1milli", 1E-3, false, false, null, MetricPrefix.None)] + [InlineData("1.23milli", 1.234E-3, false, false, 2, MetricPrefix.None)] + [InlineData("12.34k", 12345, false, true, 2, MetricPrefix.None)] + [InlineData("12k", 12345, false, true, 0, MetricPrefix.None)] + [InlineData("-3.9m", -3.91e-3, false, true, 1, MetricPrefix.None)] + [InlineData("-3.9m", -3.91e-3, false, true, 1, MetricPrefix.Mega)] + [InlineData("1M", 1_000_000, false, true, null, MetricPrefix.Giga)] + [InlineData("1000k", 1_000_000, false, true, null, MetricPrefix.Kilo)] + [InlineData("1234.56k", 1_234_560, false, true, null, MetricPrefix.Kilo)] + [InlineData("1m", 1E-3, false, true, null, MetricPrefix.None)] + [InlineData("1000μ", 1E-3, false, true, null, MetricPrefix.Micro)] + public void ToMetric(string expected, double input, bool hasSpace, bool useSymbol, int? decimals, MetricPrefix largestPrefix = MetricPrefix.None) { Assert.Equal(expected, input.ToMetric(hasSpace, useSymbol, decimals, largestPrefix)); } diff --git a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt index 4fe382785..37959238b 100644 --- a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt +++ b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt @@ -412,8 +412,8 @@ namespace Humanizer public class static MetricNumeralExtensions { public static double FromMetric(this string input) { } - public static string ToMetric(this int input, bool hasSpace = False, bool useSymbol = True, System.Nullable decimals = null, System.Nullable largestPrefix = null) { } - public static string ToMetric(this double input, bool hasSpace = False, bool useSymbol = True, System.Nullable decimals = null, System.Nullable largestPrefix = null) { } + public static string ToMetric(this int input, bool hasSpace = False, bool useSymbol = True, System.Nullable decimals = null, Humanizer.MetricPrefix largestPrefix = 0) { } + public static string ToMetric(this double input, bool hasSpace = False, bool useSymbol = True, System.Nullable decimals = null, Humanizer.MetricPrefix largestPrefix = 0) { } } public enum MetricPrefix { @@ -425,6 +425,7 @@ namespace Humanizer Nano = -9, Micro = -6, Milli = -3, + None = 0, Kilo = 3, Mega = 6, Giga = 9, diff --git a/src/Humanizer/MetricNumeralExtensions.cs b/src/Humanizer/MetricNumeralExtensions.cs index d42ea548e..bfd518e2c 100644 --- a/src/Humanizer/MetricNumeralExtensions.cs +++ b/src/Humanizer/MetricNumeralExtensions.cs @@ -111,7 +111,7 @@ public static double FromMetric(this string input) /// /// /// A valid Metric representation - public static string ToMetric(this int input, bool hasSpace = false, bool useSymbol = true, int? decimals = null, char? largestPrefix = null) + public static string ToMetric(this int input, bool hasSpace = false, bool useSymbol = true, int? decimals = null, MetricPrefix largestPrefix = MetricPrefix.None) { return ((double)input).ToMetric(hasSpace, useSymbol, decimals, largestPrefix); } @@ -137,7 +137,7 @@ public static string ToMetric(this int input, bool hasSpace = false, bool useSym /// /// /// A valid Metric representation - public static string ToMetric(this double input, bool hasSpace = false, bool useSymbol = true, int? decimals = null, char? largestPrefix = null) + public static string ToMetric(this double input, bool hasSpace = false, bool useSymbol = true, int? decimals = null, MetricPrefix largestPrefix = MetricPrefix.None) { if (input.Equals(0)) { @@ -223,7 +223,7 @@ private static string ReplaceNameBySymbol(string input) /// If not null it is the numbers of decimals to round the number to /// If not null it is the largest prefix used in result. /// A number in a Metric representation - private static string BuildRepresentation(double input, bool hasSpace, bool useSymbol, int? decimals, char? largestPrefix = null) + private static string BuildRepresentation(double input, bool hasSpace, bool useSymbol, int? decimals, MetricPrefix largestPrefix) { var exponent = (int)Math.Floor(Math.Log10(Math.Abs(input)) / 3); return exponent.Equals(0) @@ -241,10 +241,10 @@ private static string BuildRepresentation(double input, bool hasSpace, bool useS /// If not null it is the numbers of decimals to round the number to /// If not null it is the largest prefix used in result. /// A number in a Metric representation - private static string BuildMetricRepresentation(double input, int numericPrefix, bool hasSpace, bool useSymbol, int? decimals, char? largestPrefix = null) + private static string BuildMetricRepresentation(double input, int numericPrefix, bool hasSpace, bool useSymbol, int? decimals, MetricPrefix largestPrefix) { - if (largestPrefix.HasValue) - numericPrefix = LimitNumericPrefix(numericPrefix, (char)largestPrefix); + if (largestPrefix != MetricPrefix.None) + numericPrefix = LimitNumericPrefix(numericPrefix, largestPrefix); var number = input * Math.Pow(1000, -numericPrefix); @@ -266,19 +266,20 @@ private static string BuildMetricRepresentation(double input, int numericPrefix, /// Metric prefix, expressed as a number, to limit. /// Metric prefix symbol of upper limit. // TODO symbol or name. /// Upper limited numeric prefix represenation - private static int LimitNumericPrefix(int numericPrefix, char largestPrefix) + private static int LimitNumericPrefix(int numericPrefix, MetricPrefix largestPrefix) { // TODO largestPrefix = largestPrefix.Trim(); When changed to string - int maxPrefix; - if (Symbols[0].Contains(largestPrefix)) + int maxPrefix = (int)largestPrefix / 3; + + /* if (Symbols[0].Contains(largestPrefix)) maxPrefix = (Symbols[0].IndexOf(largestPrefix) + 1); else if (Symbols[1].Contains(largestPrefix)) maxPrefix = -(Symbols[1].IndexOf(largestPrefix) + 1); else - throw new ArgumentException("Invalid Metric prefix character.", nameof(largestPrefix)); // TODO change to "string". + throw new ArgumentException("Invalid Metric prefix character.", nameof(largestPrefix)); // TODO change to "string".*/ return maxPrefix < numericPrefix ? maxPrefix : numericPrefix; } diff --git a/src/Humanizer/MetricPrefix.cs b/src/Humanizer/MetricPrefix.cs index 6864c530d..9f0d1e4a5 100644 --- a/src/Humanizer/MetricPrefix.cs +++ b/src/Humanizer/MetricPrefix.cs @@ -1,7 +1,7 @@ namespace Humanizer { /// - /// MetricPrefix contains all supported metric prefixes and the corresponding powers of ten as underlying values. + /// MetricPrefix contains all supported metric prefixes and their corresponding powers of ten as underlying values. /// Unsupported: hecto, deca, deci and centi. /// public enum MetricPrefix @@ -14,6 +14,7 @@ public enum MetricPrefix Nano = -9, Micro = -6, Milli = -3, + None = 0, Kilo = 3, Mega = 6, Giga = 9, From 2ab9bd6f78173f3df634ef210d525343e25520b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bark=C3=A5?= Date: Fri, 4 Jan 2019 20:31:21 +0100 Subject: [PATCH 07/13] Added support for actual upper limit of MetricPrefix.None. Added MetricPrefix.Undefined as null equivaltent and default value for API parameter. --- .../MetricNumeralTests.cs | 35 ++++++++--------- ...provalTest.approve_public_api.approved.txt | 5 ++- src/Humanizer/MetricNumeralExtensions.cs | 38 ++++++++----------- src/Humanizer/MetricPrefix.cs | 6 ++- 4 files changed, 41 insertions(+), 43 deletions(-) diff --git a/src/Humanizer.Tests.Shared/MetricNumeralTests.cs b/src/Humanizer.Tests.Shared/MetricNumeralTests.cs index 21f250933..7ae2d37c3 100644 --- a/src/Humanizer.Tests.Shared/MetricNumeralTests.cs +++ b/src/Humanizer.Tests.Shared/MetricNumeralTests.cs @@ -90,24 +90,25 @@ public void TestAllSymbolsAsInt(int exponent) } [Theory] - [InlineData("0", 0d, false, true, null, MetricPrefix.None)] - [InlineData("123", 123d, false, true, null, MetricPrefix.None)] - [InlineData("-123", (-123d), false, true, null, MetricPrefix.None)] - [InlineData("1.23k", 1230d, false, true, null, MetricPrefix.None)] - [InlineData("1 k", 1000d, true, true, null, MetricPrefix.None)] - [InlineData("1 kilo", 1000d, true, false, null, MetricPrefix.None)] - [InlineData("1milli", 1E-3, false, false, null, MetricPrefix.None)] - [InlineData("1.23milli", 1.234E-3, false, false, 2, MetricPrefix.None)] - [InlineData("12.34k", 12345, false, true, 2, MetricPrefix.None)] - [InlineData("12k", 12345, false, true, 0, MetricPrefix.None)] - [InlineData("-3.9m", -3.91e-3, false, true, 1, MetricPrefix.None)] + [InlineData("0", 0d, false, true, null, MetricPrefix.Undefined)] + [InlineData("123", 123d, false, true, null, MetricPrefix.Undefined)] + [InlineData("-123", (-123d), false, true, null, MetricPrefix.Undefined)] + [InlineData("1.23k", 1230d, false, true, null, MetricPrefix.Undefined)] + [InlineData("1 k", 1000d, true, true, null, MetricPrefix.Undefined)] + [InlineData("1 kilo", 1000d, true, false, null, MetricPrefix.Undefined)] + [InlineData("1milli", 1E-3, false, false, null, MetricPrefix.Undefined)] + [InlineData("1.23milli", 1.234E-3, false, false, 2, MetricPrefix.Undefined)] + [InlineData("12.34k", 12345, false, true, 2, MetricPrefix.Undefined)] + [InlineData("12k", 12345, false, true, 0, MetricPrefix.Undefined)] + [InlineData("-3.9m", -3.91e-3, false, true, 1, MetricPrefix.Undefined)] [InlineData("-3.9m", -3.91e-3, false, true, 1, MetricPrefix.Mega)] - [InlineData("1M", 1_000_000, false, true, null, MetricPrefix.Giga)] - [InlineData("1000k", 1_000_000, false, true, null, MetricPrefix.Kilo)] - [InlineData("1234.56k", 1_234_560, false, true, null, MetricPrefix.Kilo)] - [InlineData("1m", 1E-3, false, true, null, MetricPrefix.None)] - [InlineData("1000μ", 1E-3, false, true, null, MetricPrefix.Micro)] - public void ToMetric(string expected, double input, bool hasSpace, bool useSymbol, int? decimals, MetricPrefix largestPrefix = MetricPrefix.None) + [InlineData("1M", 1_000_000, false, true, null, MetricPrefix.Giga)] + [InlineData("1000k", 1_000_000, false, true, null, MetricPrefix.Kilo)] + [InlineData("1234.56k", 1_234_560, false, true, null, MetricPrefix.Kilo)] + [InlineData("1m", 1E-3, false, true, null, MetricPrefix.Undefined)] + [InlineData("1000μ", 1E-3, false, true, null, MetricPrefix.Micro)] + [InlineData("1000", 1000, false, true, null, MetricPrefix.None)] + public void ToMetric(string expected, double input, bool hasSpace, bool useSymbol, int? decimals, MetricPrefix largestPrefix) { Assert.Equal(expected, input.ToMetric(hasSpace, useSymbol, decimals, largestPrefix)); } diff --git a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt index 37959238b..7e6922d75 100644 --- a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt +++ b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt @@ -412,11 +412,12 @@ namespace Humanizer public class static MetricNumeralExtensions { public static double FromMetric(this string input) { } - public static string ToMetric(this int input, bool hasSpace = False, bool useSymbol = True, System.Nullable decimals = null, Humanizer.MetricPrefix largestPrefix = 0) { } - public static string ToMetric(this double input, bool hasSpace = False, bool useSymbol = True, System.Nullable decimals = null, Humanizer.MetricPrefix largestPrefix = 0) { } + public static string ToMetric(this int input, bool hasSpace = False, bool useSymbol = True, System.Nullable decimals = null, Humanizer.MetricPrefix largestPrefix = -100) { } + public static string ToMetric(this double input, bool hasSpace = False, bool useSymbol = True, System.Nullable decimals = null, Humanizer.MetricPrefix largestPrefix = -100) { } } public enum MetricPrefix { + Undefined = -100, Yocto = -24, Zepto = -21, Atto = -18, diff --git a/src/Humanizer/MetricNumeralExtensions.cs b/src/Humanizer/MetricNumeralExtensions.cs index bfd518e2c..bc26add75 100644 --- a/src/Humanizer/MetricNumeralExtensions.cs +++ b/src/Humanizer/MetricNumeralExtensions.cs @@ -101,17 +101,17 @@ public static double FromMetric(this string input) /// True will split the number and the symbol with a whitespace. /// True will use symbol instead of name /// If not null it is the numbers of decimals to round the number to - /// If not null it is the largest prefix used in result. + /// Largest metric prefix used in result. /// /// /// 1000.ToMetric() => "1k" /// 123.ToMetric() => "123" /// 1E-1.ToMetric() => "100m" - /// 1_000_000.ToMetric(largestPrefix = 'k') => "1000k" + /// 1_000_000.ToMetric(largestPrefix = MetricPrefix.Kilo) => "1000k" /// /// /// A valid Metric representation - public static string ToMetric(this int input, bool hasSpace = false, bool useSymbol = true, int? decimals = null, MetricPrefix largestPrefix = MetricPrefix.None) + public static string ToMetric(this int input, bool hasSpace = false, bool useSymbol = true, int? decimals = null, MetricPrefix largestPrefix = MetricPrefix.Undefined) { return ((double)input).ToMetric(hasSpace, useSymbol, decimals, largestPrefix); } @@ -127,17 +127,17 @@ public static string ToMetric(this int input, bool hasSpace = false, bool useSym /// True will split the number and the symbol with a whitespace. /// True will use symbol instead of name /// If not null it is the numbers of decimals to round the number to - /// If not null it is the largest prefix used in result. + /// Largest metric prefix used in result. /// /// /// 1000d.ToMetric() => "1k" /// 123d.ToMetric() => "123" /// 1E-1.ToMetric() => "100m" - /// 1_000_000.ToMetric(largestPrefix = 'k') => "1000k" + /// 1_000_000.ToMetric(largestPrefix = MetricPrefix.Kilo) => "1000k" /// /// /// A valid Metric representation - public static string ToMetric(this double input, bool hasSpace = false, bool useSymbol = true, int? decimals = null, MetricPrefix largestPrefix = MetricPrefix.None) + public static string ToMetric(this double input, bool hasSpace = false, bool useSymbol = true, int? decimals = null, MetricPrefix largestPrefix = MetricPrefix.Undefined) { if (input.Equals(0)) { @@ -221,7 +221,7 @@ private static string ReplaceNameBySymbol(string input) /// True will split the number and the symbol with a whitespace. /// True will use symbol instead of name /// If not null it is the numbers of decimals to round the number to - /// If not null it is the largest prefix used in result. + /// Largest metric prefix used in result. /// A number in a Metric representation private static string BuildRepresentation(double input, bool hasSpace, bool useSymbol, int? decimals, MetricPrefix largestPrefix) { @@ -239,13 +239,16 @@ private static string BuildRepresentation(double input, bool hasSpace, bool useS /// True will split the number and the symbol with a whitespace. /// True will use symbol instead of name /// If not null it is the numbers of decimals to round the number to - /// If not null it is the largest prefix used in result. + /// Largest metric prefix used in result. /// A number in a Metric representation private static string BuildMetricRepresentation(double input, int numericPrefix, bool hasSpace, bool useSymbol, int? decimals, MetricPrefix largestPrefix) { - if (largestPrefix != MetricPrefix.None) + if (largestPrefix != MetricPrefix.Undefined) numericPrefix = LimitNumericPrefix(numericPrefix, largestPrefix); + if (numericPrefix == 0) + return input.ToString(); + var number = input * Math.Pow(1000, -numericPrefix); if (decimals.HasValue) @@ -264,22 +267,11 @@ private static string BuildMetricRepresentation(double input, int numericPrefix, /// Limit upper size of a numeric representation of metric prefix. /// /// Metric prefix, expressed as a number, to limit. - /// Metric prefix symbol of upper limit. // TODO symbol or name. - /// Upper limited numeric prefix represenation + /// Upper limit. + /// Upper limited numeric prefix representation private static int LimitNumericPrefix(int numericPrefix, MetricPrefix largestPrefix) { - // TODO largestPrefix = largestPrefix.Trim(); When changed to string - - int maxPrefix = (int)largestPrefix / 3; - - /* if (Symbols[0].Contains(largestPrefix)) - maxPrefix = (Symbols[0].IndexOf(largestPrefix) + 1); - - else if (Symbols[1].Contains(largestPrefix)) - maxPrefix = -(Symbols[1].IndexOf(largestPrefix) + 1); - - else - throw new ArgumentException("Invalid Metric prefix character.", nameof(largestPrefix)); // TODO change to "string".*/ + var maxPrefix = (int)largestPrefix / 3; return maxPrefix < numericPrefix ? maxPrefix : numericPrefix; } diff --git a/src/Humanizer/MetricPrefix.cs b/src/Humanizer/MetricPrefix.cs index 9f0d1e4a5..37ca9b9f6 100644 --- a/src/Humanizer/MetricPrefix.cs +++ b/src/Humanizer/MetricPrefix.cs @@ -2,10 +2,14 @@ { /// /// MetricPrefix contains all supported metric prefixes and their corresponding powers of ten as underlying values. - /// Unsupported: hecto, deca, deci and centi. /// + /// + /// "None" represents no prefix, use "Undefined" as null equivalent. + /// Unsupported values: hecto, deca, deci and centi. + /// public enum MetricPrefix { + Undefined = -100, Yocto = -24, Zepto = -21, Atto = -18, From 2386e96fd235fcb5e2861026248f423d570ae75a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bark=C3=A5?= Date: Sun, 6 Jan 2019 12:04:23 +0100 Subject: [PATCH 08/13] Changed parameter name to maxPrefix. --- .../MetricNumeralTests.cs | 4 +-- ...provalTest.approve_public_api.approved.txt | 4 +-- src/Humanizer/MetricNumeralExtensions.cs | 34 +++++++++---------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/Humanizer.Tests.Shared/MetricNumeralTests.cs b/src/Humanizer.Tests.Shared/MetricNumeralTests.cs index 7ae2d37c3..be921786a 100644 --- a/src/Humanizer.Tests.Shared/MetricNumeralTests.cs +++ b/src/Humanizer.Tests.Shared/MetricNumeralTests.cs @@ -108,9 +108,9 @@ public void TestAllSymbolsAsInt(int exponent) [InlineData("1m", 1E-3, false, true, null, MetricPrefix.Undefined)] [InlineData("1000μ", 1E-3, false, true, null, MetricPrefix.Micro)] [InlineData("1000", 1000, false, true, null, MetricPrefix.None)] - public void ToMetric(string expected, double input, bool hasSpace, bool useSymbol, int? decimals, MetricPrefix largestPrefix) + public void ToMetric(string expected, double input, bool hasSpace, bool useSymbol, int? decimals, MetricPrefix maxPrefix) { - Assert.Equal(expected, input.ToMetric(hasSpace, useSymbol, decimals, largestPrefix)); + Assert.Equal(expected, input.ToMetric(hasSpace, useSymbol, decimals, maxPrefix)); } [Theory] diff --git a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt index 7e6922d75..a72ecb762 100644 --- a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt +++ b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt @@ -412,8 +412,8 @@ namespace Humanizer public class static MetricNumeralExtensions { public static double FromMetric(this string input) { } - public static string ToMetric(this int input, bool hasSpace = False, bool useSymbol = True, System.Nullable decimals = null, Humanizer.MetricPrefix largestPrefix = -100) { } - public static string ToMetric(this double input, bool hasSpace = False, bool useSymbol = True, System.Nullable decimals = null, Humanizer.MetricPrefix largestPrefix = -100) { } + public static string ToMetric(this int input, bool hasSpace = False, bool useSymbol = True, System.Nullable decimals = null, Humanizer.MetricPrefix maxPrefix = -100) { } + public static string ToMetric(this double input, bool hasSpace = False, bool useSymbol = True, System.Nullable decimals = null, Humanizer.MetricPrefix maxPrefix = -100) { } } public enum MetricPrefix { diff --git a/src/Humanizer/MetricNumeralExtensions.cs b/src/Humanizer/MetricNumeralExtensions.cs index bc26add75..3329b7e94 100644 --- a/src/Humanizer/MetricNumeralExtensions.cs +++ b/src/Humanizer/MetricNumeralExtensions.cs @@ -101,7 +101,7 @@ public static double FromMetric(this string input) /// True will split the number and the symbol with a whitespace. /// True will use symbol instead of name /// If not null it is the numbers of decimals to round the number to - /// Largest metric prefix used in result. + /// Largest metric prefix used in result. /// /// /// 1000.ToMetric() => "1k" @@ -111,9 +111,9 @@ public static double FromMetric(this string input) /// /// /// A valid Metric representation - public static string ToMetric(this int input, bool hasSpace = false, bool useSymbol = true, int? decimals = null, MetricPrefix largestPrefix = MetricPrefix.Undefined) + public static string ToMetric(this int input, bool hasSpace = false, bool useSymbol = true, int? decimals = null, MetricPrefix maxPrefix = MetricPrefix.Undefined) { - return ((double)input).ToMetric(hasSpace, useSymbol, decimals, largestPrefix); + return ((double)input).ToMetric(hasSpace, useSymbol, decimals, maxPrefix); } /// @@ -127,7 +127,7 @@ public static string ToMetric(this int input, bool hasSpace = false, bool useSym /// True will split the number and the symbol with a whitespace. /// True will use symbol instead of name /// If not null it is the numbers of decimals to round the number to - /// Largest metric prefix used in result. + /// Largest metric prefix used in result. /// /// /// 1000d.ToMetric() => "1k" @@ -137,7 +137,7 @@ public static string ToMetric(this int input, bool hasSpace = false, bool useSym /// /// /// A valid Metric representation - public static string ToMetric(this double input, bool hasSpace = false, bool useSymbol = true, int? decimals = null, MetricPrefix largestPrefix = MetricPrefix.Undefined) + public static string ToMetric(this double input, bool hasSpace = false, bool useSymbol = true, int? decimals = null, MetricPrefix maxPrefix = MetricPrefix.Undefined) { if (input.Equals(0)) { @@ -149,7 +149,7 @@ public static string ToMetric(this double input, bool hasSpace = false, bool use throw new ArgumentOutOfRangeException(nameof(input)); } - return BuildRepresentation(input, hasSpace, useSymbol, decimals, largestPrefix); + return BuildRepresentation(input, hasSpace, useSymbol, decimals, maxPrefix); } /// @@ -221,14 +221,14 @@ private static string ReplaceNameBySymbol(string input) /// True will split the number and the symbol with a whitespace. /// True will use symbol instead of name /// If not null it is the numbers of decimals to round the number to - /// Largest metric prefix used in result. + /// Largest metric prefix used in result. /// A number in a Metric representation - private static string BuildRepresentation(double input, bool hasSpace, bool useSymbol, int? decimals, MetricPrefix largestPrefix) + private static string BuildRepresentation(double input, bool hasSpace, bool useSymbol, int? decimals, MetricPrefix maxPrefix) { var exponent = (int)Math.Floor(Math.Log10(Math.Abs(input)) / 3); return exponent.Equals(0) ? input.ToString() - : BuildMetricRepresentation(input, exponent, hasSpace, useSymbol, decimals, largestPrefix); + : BuildMetricRepresentation(input, exponent, hasSpace, useSymbol, decimals, maxPrefix); } /// @@ -239,12 +239,12 @@ private static string BuildRepresentation(double input, bool hasSpace, bool useS /// True will split the number and the symbol with a whitespace. /// True will use symbol instead of name /// If not null it is the numbers of decimals to round the number to - /// Largest metric prefix used in result. + /// Largest metric prefix used in result. /// A number in a Metric representation - private static string BuildMetricRepresentation(double input, int numericPrefix, bool hasSpace, bool useSymbol, int? decimals, MetricPrefix largestPrefix) + private static string BuildMetricRepresentation(double input, int numericPrefix, bool hasSpace, bool useSymbol, int? decimals, MetricPrefix maxPrefix) { - if (largestPrefix != MetricPrefix.Undefined) - numericPrefix = LimitNumericPrefix(numericPrefix, largestPrefix); + if (maxPrefix != MetricPrefix.Undefined) + numericPrefix = LimitNumericPrefix(numericPrefix, maxPrefix); if (numericPrefix == 0) return input.ToString(); @@ -267,13 +267,13 @@ private static string BuildMetricRepresentation(double input, int numericPrefix, /// Limit upper size of a numeric representation of metric prefix. /// /// Metric prefix, expressed as a number, to limit. - /// Upper limit. + /// Upper limit. /// Upper limited numeric prefix representation - private static int LimitNumericPrefix(int numericPrefix, MetricPrefix largestPrefix) + private static int LimitNumericPrefix(int numericPrefix, MetricPrefix maxPrefix) { - var maxPrefix = (int)largestPrefix / 3; + var maxNumericPrefix = (int)maxPrefix / 3; - return maxPrefix < numericPrefix ? maxPrefix : numericPrefix; + return maxNumericPrefix < numericPrefix ? maxNumericPrefix : numericPrefix; } /// From 03e1f8d9ae667c971cd201bd1a1d936fcab03531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bark=C3=A5?= Date: Sun, 6 Jan 2019 12:16:10 +0100 Subject: [PATCH 09/13] Added nonfunctional minPrefix "stub", in fututre versions mirroring the functionality of maxPrefix. --- .../MetricNumeralTests.cs | 40 +++++++++---------- ...provalTest.approve_public_api.approved.txt | 4 +- src/Humanizer/MetricNumeralExtensions.cs | 16 ++++---- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/Humanizer.Tests.Shared/MetricNumeralTests.cs b/src/Humanizer.Tests.Shared/MetricNumeralTests.cs index be921786a..0ec020fb7 100644 --- a/src/Humanizer.Tests.Shared/MetricNumeralTests.cs +++ b/src/Humanizer.Tests.Shared/MetricNumeralTests.cs @@ -90,27 +90,27 @@ public void TestAllSymbolsAsInt(int exponent) } [Theory] - [InlineData("0", 0d, false, true, null, MetricPrefix.Undefined)] - [InlineData("123", 123d, false, true, null, MetricPrefix.Undefined)] - [InlineData("-123", (-123d), false, true, null, MetricPrefix.Undefined)] - [InlineData("1.23k", 1230d, false, true, null, MetricPrefix.Undefined)] - [InlineData("1 k", 1000d, true, true, null, MetricPrefix.Undefined)] - [InlineData("1 kilo", 1000d, true, false, null, MetricPrefix.Undefined)] - [InlineData("1milli", 1E-3, false, false, null, MetricPrefix.Undefined)] - [InlineData("1.23milli", 1.234E-3, false, false, 2, MetricPrefix.Undefined)] - [InlineData("12.34k", 12345, false, true, 2, MetricPrefix.Undefined)] - [InlineData("12k", 12345, false, true, 0, MetricPrefix.Undefined)] - [InlineData("-3.9m", -3.91e-3, false, true, 1, MetricPrefix.Undefined)] - [InlineData("-3.9m", -3.91e-3, false, true, 1, MetricPrefix.Mega)] - [InlineData("1M", 1_000_000, false, true, null, MetricPrefix.Giga)] - [InlineData("1000k", 1_000_000, false, true, null, MetricPrefix.Kilo)] - [InlineData("1234.56k", 1_234_560, false, true, null, MetricPrefix.Kilo)] - [InlineData("1m", 1E-3, false, true, null, MetricPrefix.Undefined)] - [InlineData("1000μ", 1E-3, false, true, null, MetricPrefix.Micro)] - [InlineData("1000", 1000, false, true, null, MetricPrefix.None)] - public void ToMetric(string expected, double input, bool hasSpace, bool useSymbol, int? decimals, MetricPrefix maxPrefix) + [InlineData("0", 0d, false, true, null, MetricPrefix.Undefined, MetricPrefix.Undefined)] + [InlineData("123", 123d, false, true, null, MetricPrefix.Undefined, MetricPrefix.Undefined)] + [InlineData("-123", (-123d), false, true, null, MetricPrefix.Undefined, MetricPrefix.Undefined)] + [InlineData("1.23k", 1230d, false, true, null, MetricPrefix.Undefined, MetricPrefix.Undefined)] + [InlineData("1 k", 1000d, true, true, null, MetricPrefix.Undefined, MetricPrefix.Undefined)] + [InlineData("1 kilo", 1000d, true, false, null, MetricPrefix.Undefined, MetricPrefix.Undefined)] + [InlineData("1milli", 1E-3, false, false, null, MetricPrefix.Undefined, MetricPrefix.Undefined)] + [InlineData("1.23milli", 1.234E-3, false, false, 2, MetricPrefix.Undefined, MetricPrefix.Undefined)] + [InlineData("12.34k", 12345, false, true, 2, MetricPrefix.Undefined, MetricPrefix.Undefined)] + [InlineData("12k", 12345, false, true, 0, MetricPrefix.Undefined, MetricPrefix.Undefined)] + [InlineData("-3.9m", -3.91e-3, false, true, 1, MetricPrefix.Undefined, MetricPrefix.Undefined)] + [InlineData("-3.9m", -3.91e-3, false, true, 1, MetricPrefix.Mega, MetricPrefix.Undefined)] + [InlineData("1M", 1_000_000, false, true, null, MetricPrefix.Giga, MetricPrefix.Undefined)] + [InlineData("1000k", 1_000_000, false, true, null, MetricPrefix.Kilo, MetricPrefix.Undefined)] + [InlineData("1234.56k", 1_234_560, false, true, null, MetricPrefix.Kilo, MetricPrefix.Undefined)] + [InlineData("1m", 1E-3, false, true, null, MetricPrefix.Undefined, MetricPrefix.Undefined)] + [InlineData("1000μ", 1E-3, false, true, null, MetricPrefix.Micro, MetricPrefix.Undefined)] + [InlineData("1000", 1000, false, true, null, MetricPrefix.None, MetricPrefix.Undefined)] + public void ToMetric(string expected, double input, bool hasSpace, bool useSymbol, int? decimals, MetricPrefix maxPrefix, MetricPrefix minPrefix) { - Assert.Equal(expected, input.ToMetric(hasSpace, useSymbol, decimals, maxPrefix)); + Assert.Equal(expected, input.ToMetric(hasSpace, useSymbol, decimals, maxPrefix, minPrefix)); } [Theory] diff --git a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt index a72ecb762..a34c8bf5a 100644 --- a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt +++ b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt @@ -412,8 +412,8 @@ namespace Humanizer public class static MetricNumeralExtensions { public static double FromMetric(this string input) { } - public static string ToMetric(this int input, bool hasSpace = False, bool useSymbol = True, System.Nullable decimals = null, Humanizer.MetricPrefix maxPrefix = -100) { } - public static string ToMetric(this double input, bool hasSpace = False, bool useSymbol = True, System.Nullable decimals = null, Humanizer.MetricPrefix maxPrefix = -100) { } + public static string ToMetric(this int input, bool hasSpace = False, bool useSymbol = True, System.Nullable decimals = null, Humanizer.MetricPrefix maxPrefix = -100, Humanizer.MetricPrefix minPrefix = -100) { } + public static string ToMetric(this double input, bool hasSpace = False, bool useSymbol = True, System.Nullable decimals = null, Humanizer.MetricPrefix maxPrefix = -100, Humanizer.MetricPrefix minPrefix = -100) { } } public enum MetricPrefix { diff --git a/src/Humanizer/MetricNumeralExtensions.cs b/src/Humanizer/MetricNumeralExtensions.cs index 3329b7e94..291a00f00 100644 --- a/src/Humanizer/MetricNumeralExtensions.cs +++ b/src/Humanizer/MetricNumeralExtensions.cs @@ -111,7 +111,7 @@ public static double FromMetric(this string input) /// /// /// A valid Metric representation - public static string ToMetric(this int input, bool hasSpace = false, bool useSymbol = true, int? decimals = null, MetricPrefix maxPrefix = MetricPrefix.Undefined) + public static string ToMetric(this int input, bool hasSpace = false, bool useSymbol = true, int? decimals = null, MetricPrefix maxPrefix = MetricPrefix.Undefined, MetricPrefix minPrefix = MetricPrefix.Undefined) { return ((double)input).ToMetric(hasSpace, useSymbol, decimals, maxPrefix); } @@ -137,7 +137,7 @@ public static string ToMetric(this int input, bool hasSpace = false, bool useSym /// /// /// A valid Metric representation - public static string ToMetric(this double input, bool hasSpace = false, bool useSymbol = true, int? decimals = null, MetricPrefix maxPrefix = MetricPrefix.Undefined) + public static string ToMetric(this double input, bool hasSpace = false, bool useSymbol = true, int? decimals = null, MetricPrefix maxPrefix = MetricPrefix.Undefined, MetricPrefix minPrefix = MetricPrefix.Undefined) { if (input.Equals(0)) { @@ -149,7 +149,7 @@ public static string ToMetric(this double input, bool hasSpace = false, bool use throw new ArgumentOutOfRangeException(nameof(input)); } - return BuildRepresentation(input, hasSpace, useSymbol, decimals, maxPrefix); + return BuildRepresentation(input, hasSpace, useSymbol, decimals, maxPrefix, minPrefix); } /// @@ -223,12 +223,12 @@ private static string ReplaceNameBySymbol(string input) /// If not null it is the numbers of decimals to round the number to /// Largest metric prefix used in result. /// A number in a Metric representation - private static string BuildRepresentation(double input, bool hasSpace, bool useSymbol, int? decimals, MetricPrefix maxPrefix) + private static string BuildRepresentation(double input, bool hasSpace, bool useSymbol, int? decimals, MetricPrefix maxPrefix, MetricPrefix minPrefix) { var exponent = (int)Math.Floor(Math.Log10(Math.Abs(input)) / 3); return exponent.Equals(0) ? input.ToString() - : BuildMetricRepresentation(input, exponent, hasSpace, useSymbol, decimals, maxPrefix); + : BuildMetricRepresentation(input, exponent, hasSpace, useSymbol, decimals, maxPrefix, minPrefix); } /// @@ -241,10 +241,10 @@ private static string BuildRepresentation(double input, bool hasSpace, bool useS /// If not null it is the numbers of decimals to round the number to /// Largest metric prefix used in result. /// A number in a Metric representation - private static string BuildMetricRepresentation(double input, int numericPrefix, bool hasSpace, bool useSymbol, int? decimals, MetricPrefix maxPrefix) + private static string BuildMetricRepresentation(double input, int numericPrefix, bool hasSpace, bool useSymbol, int? decimals, MetricPrefix maxPrefix, MetricPrefix minPrefix) { if (maxPrefix != MetricPrefix.Undefined) - numericPrefix = LimitNumericPrefix(numericPrefix, maxPrefix); + numericPrefix = LimitNumericPrefix(numericPrefix, maxPrefix, minPrefix); if (numericPrefix == 0) return input.ToString(); @@ -269,7 +269,7 @@ private static string BuildMetricRepresentation(double input, int numericPrefix, /// Metric prefix, expressed as a number, to limit. /// Upper limit. /// Upper limited numeric prefix representation - private static int LimitNumericPrefix(int numericPrefix, MetricPrefix maxPrefix) + private static int LimitNumericPrefix(int numericPrefix, MetricPrefix maxPrefix, MetricPrefix minPrefix) { var maxNumericPrefix = (int)maxPrefix / 3; From 2fe1c4600eb41b9d22190e53f07c831bf147aad4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bark=C3=A5?= Date: Sun, 6 Jan 2019 17:59:30 +0100 Subject: [PATCH 10/13] Added functionality for "minPrefix". Interaction with "decimals" might be undesireable. --- .../MetricNumeralTests.cs | 44 +++++++++++-------- src/Humanizer/MetricNumeralExtensions.cs | 29 ++++++++---- 2 files changed, 47 insertions(+), 26 deletions(-) diff --git a/src/Humanizer.Tests.Shared/MetricNumeralTests.cs b/src/Humanizer.Tests.Shared/MetricNumeralTests.cs index 0ec020fb7..b84c7f356 100644 --- a/src/Humanizer.Tests.Shared/MetricNumeralTests.cs +++ b/src/Humanizer.Tests.Shared/MetricNumeralTests.cs @@ -90,24 +90,32 @@ public void TestAllSymbolsAsInt(int exponent) } [Theory] - [InlineData("0", 0d, false, true, null, MetricPrefix.Undefined, MetricPrefix.Undefined)] - [InlineData("123", 123d, false, true, null, MetricPrefix.Undefined, MetricPrefix.Undefined)] - [InlineData("-123", (-123d), false, true, null, MetricPrefix.Undefined, MetricPrefix.Undefined)] - [InlineData("1.23k", 1230d, false, true, null, MetricPrefix.Undefined, MetricPrefix.Undefined)] - [InlineData("1 k", 1000d, true, true, null, MetricPrefix.Undefined, MetricPrefix.Undefined)] - [InlineData("1 kilo", 1000d, true, false, null, MetricPrefix.Undefined, MetricPrefix.Undefined)] - [InlineData("1milli", 1E-3, false, false, null, MetricPrefix.Undefined, MetricPrefix.Undefined)] - [InlineData("1.23milli", 1.234E-3, false, false, 2, MetricPrefix.Undefined, MetricPrefix.Undefined)] - [InlineData("12.34k", 12345, false, true, 2, MetricPrefix.Undefined, MetricPrefix.Undefined)] - [InlineData("12k", 12345, false, true, 0, MetricPrefix.Undefined, MetricPrefix.Undefined)] - [InlineData("-3.9m", -3.91e-3, false, true, 1, MetricPrefix.Undefined, MetricPrefix.Undefined)] - [InlineData("-3.9m", -3.91e-3, false, true, 1, MetricPrefix.Mega, MetricPrefix.Undefined)] - [InlineData("1M", 1_000_000, false, true, null, MetricPrefix.Giga, MetricPrefix.Undefined)] - [InlineData("1000k", 1_000_000, false, true, null, MetricPrefix.Kilo, MetricPrefix.Undefined)] - [InlineData("1234.56k", 1_234_560, false, true, null, MetricPrefix.Kilo, MetricPrefix.Undefined)] - [InlineData("1m", 1E-3, false, true, null, MetricPrefix.Undefined, MetricPrefix.Undefined)] - [InlineData("1000μ", 1E-3, false, true, null, MetricPrefix.Micro, MetricPrefix.Undefined)] - [InlineData("1000", 1000, false, true, null, MetricPrefix.None, MetricPrefix.Undefined)] + [InlineData("0", 0d, false, true, null, MetricPrefix.Undefined, MetricPrefix.Undefined)] + [InlineData("123", 123d, false, true, null, MetricPrefix.Undefined, MetricPrefix.Undefined)] + [InlineData("-123", (-123d), false, true, null, MetricPrefix.Undefined, MetricPrefix.Undefined)] + [InlineData("1.23k", 1230d, false, true, null, MetricPrefix.Undefined, MetricPrefix.Undefined)] + [InlineData("1 k", 1000d, true, true, null, MetricPrefix.Undefined, MetricPrefix.Undefined)] + [InlineData("1 kilo", 1000d, true, false, null, MetricPrefix.Undefined, MetricPrefix.Undefined)] + [InlineData("1milli", 1E-3, false, false, null, MetricPrefix.Undefined, MetricPrefix.Undefined)] + [InlineData("1.23milli", 1.234E-3, false, false, 2, MetricPrefix.Undefined, MetricPrefix.Undefined)] + [InlineData("12.34k", 12345, false, true, 2, MetricPrefix.Undefined, MetricPrefix.Undefined)] + [InlineData("12k", 12345, false, true, 0, MetricPrefix.Undefined, MetricPrefix.Undefined)] + [InlineData("-3.9m", -3.91e-3, false, true, 1, MetricPrefix.Undefined, MetricPrefix.Undefined)] + [InlineData("-3.9m", -3.91e-3, false, true, 1, MetricPrefix.Mega, MetricPrefix.Undefined)] + [InlineData("1.23", 1.23, false, true, 1, MetricPrefix.Mega, MetricPrefix.Undefined)] // Expected behavior or bug? + [InlineData("1M", 1E6, false, true, null, MetricPrefix.Giga, MetricPrefix.Undefined)] + [InlineData("1000k", 1E6, false, true, null, MetricPrefix.Kilo, MetricPrefix.Undefined)] + [InlineData("1234.56k", 1_234_560, false, true, null, MetricPrefix.Kilo, MetricPrefix.Undefined)] + [InlineData("1m", 1E-3, false, true, null, MetricPrefix.Undefined, MetricPrefix.Undefined)] + [InlineData("1000μ", 1E-3, false, true, null, MetricPrefix.Micro, MetricPrefix.Undefined)] + [InlineData("1000", 1000, false, true, null, MetricPrefix.None, MetricPrefix.Undefined)] + [InlineData("0.001m", 1E-6, false, true, null, MetricPrefix.Undefined, MetricPrefix.Milli)] + [InlineData("0m", 1E-6, false, true, 0, MetricPrefix.Undefined, MetricPrefix.Milli)] + [InlineData("0.01m", 1.234E-5, false, true, 2, MetricPrefix.Undefined, MetricPrefix.Milli)] + [InlineData("12.34μ", 1.2345E-5, false, true, 2, MetricPrefix.Undefined, MetricPrefix.Micro)] + [InlineData("0.01μ", 1.2345E-8, false, true, 2, MetricPrefix.Undefined, MetricPrefix.Micro)] + + public void ToMetric(string expected, double input, bool hasSpace, bool useSymbol, int? decimals, MetricPrefix maxPrefix, MetricPrefix minPrefix) { Assert.Equal(expected, input.ToMetric(hasSpace, useSymbol, decimals, maxPrefix, minPrefix)); diff --git a/src/Humanizer/MetricNumeralExtensions.cs b/src/Humanizer/MetricNumeralExtensions.cs index 291a00f00..9e37232a2 100644 --- a/src/Humanizer/MetricNumeralExtensions.cs +++ b/src/Humanizer/MetricNumeralExtensions.cs @@ -240,11 +240,11 @@ private static string BuildRepresentation(double input, bool hasSpace, bool useS /// True will use symbol instead of name /// If not null it is the numbers of decimals to round the number to /// Largest metric prefix used in result. + /// Smallest metric prefix used in result. /// A number in a Metric representation private static string BuildMetricRepresentation(double input, int numericPrefix, bool hasSpace, bool useSymbol, int? decimals, MetricPrefix maxPrefix, MetricPrefix minPrefix) { - if (maxPrefix != MetricPrefix.Undefined) - numericPrefix = LimitNumericPrefix(numericPrefix, maxPrefix, minPrefix); + numericPrefix = numericPrefix.Clamp(minPrefix, maxPrefix); if (numericPrefix == 0) return input.ToString(); @@ -256,7 +256,7 @@ private static string BuildMetricRepresentation(double input, int numericPrefix, var symbol = Math.Sign(numericPrefix) == 1 ? Symbols[0][numericPrefix - 1] - : Symbols[1][-numericPrefix - 1]; + : Symbols[1][-numericPrefix - 1]; return number + (hasSpace ? " " : string.Empty) @@ -264,16 +264,29 @@ private static string BuildMetricRepresentation(double input, int numericPrefix, } /// - /// Limit upper size of a numeric representation of metric prefix. + /// Clamps a numeric representation of metric prefix. /// /// Metric prefix, expressed as a number, to limit. + /// Lower limit. /// Upper limit. - /// Upper limited numeric prefix representation - private static int LimitNumericPrefix(int numericPrefix, MetricPrefix maxPrefix, MetricPrefix minPrefix) + /// Clamped numeric prefix representation + private static int Clamp(this int numericPrefix, MetricPrefix minPrefix, MetricPrefix maxPrefix) { - var maxNumericPrefix = (int)maxPrefix / 3; + if (maxPrefix == MetricPrefix.Undefined && minPrefix == MetricPrefix.Undefined) + return numericPrefix; + + if (maxPrefix != MetricPrefix.Undefined && minPrefix != MetricPrefix.Undefined && maxPrefix < minPrefix) + throw new ArgumentException($"{nameof(maxPrefix)} can't be smaller than {nameof(minPrefix)}."); - return maxNumericPrefix < numericPrefix ? maxNumericPrefix : numericPrefix; + var maxNumericPrefix = (int)maxPrefix / 3; + var minNumericPrefix = (int)minPrefix / 3; + + if (maxPrefix != MetricPrefix.Undefined && maxNumericPrefix < numericPrefix) + return maxNumericPrefix; + else if (minPrefix != MetricPrefix.Undefined && minNumericPrefix > numericPrefix) + return minNumericPrefix; + else + return numericPrefix; } /// From 1b029b5997c6e4c8904a45301c85e9d94d20e94d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bark=C3=A5?= Date: Mon, 7 Jan 2019 14:13:10 +0100 Subject: [PATCH 11/13] Updated readme with current as well as new options. --- readme.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 135aae71c..ed67c7201 100644 --- a/readme.md +++ b/readme.md @@ -899,7 +899,17 @@ Humanizer can change numbers to Metric numerals using the `ToMetric` extension. 0.1d.ToMetric() => "100m" ``` -Also the reverse operation using the `FromMetric` extension. +`ToMetric` accepts a several named optional parameters: + +Type | Name | Default | Description +------------ | ------------- | ------------- | ------------- +bool | hasSpace | false | True adds a space between the number and metric prefix. +bool | useSymbol | true | False adds the full name of the metric prefix. +int? | decimals | null | Max number of decimals in the numeric part of the output. +MetricPrefix | maxPrefix | Undefined | Sets an upper limit to the used metric prefix. +MetricPrefix | minPrefix | Undefined | Sets a lower limit to the used metric prefix. + +Humanizer also has the reverse operation using the `FromMetric` extension. ```C# 1d.ToMetric() => "1" From 04d611c8b3533c3ea85a27effb595723f11fc4c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bark=C3=A5?= Date: Mon, 7 Jan 2019 16:40:07 +0100 Subject: [PATCH 12/13] Added examples to readme. --- readme.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/readme.md b/readme.md index ed67c7201..e6423ea9f 100644 --- a/readme.md +++ b/readme.md @@ -909,6 +909,15 @@ int? | decimals | null | Max number of decimals in the numeric part of the outpu MetricPrefix | maxPrefix | Undefined | Sets an upper limit to the used metric prefix. MetricPrefix | minPrefix | Undefined | Sets a lower limit to the used metric prefix. +Examples: +```C# +1000.ToMetric(hasSpace: true) => "1 k" +1000.ToMetric(useSymbol: false) => "1kilo" +1234.ToMetric(decimals: 1) => "1.2k" +1E6.ToMetric(maxPrefix: MetricPrefix.Kilo) => "1000k" +1E-6.ToMetric(minPrefix: MetricPrefix.Milli) => "0.001m" +``` + Humanizer also has the reverse operation using the `FromMetric` extension. ```C# From f1ef468dbf38b4c3876b59930ed0f409c9809d5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bark=C3=A5?= Date: Thu, 10 Jan 2019 18:48:46 +0100 Subject: [PATCH 13/13] Updated copyright notice, minor readme and test comments changes. --- readme.md | 4 ++-- src/Humanizer.Tests.Shared/MetricNumeralTests.cs | 6 ++---- src/Humanizer/MetricNumeralExtensions.cs | 4 ++-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/readme.md b/readme.md index e6423ea9f..bea3af076 100644 --- a/readme.md +++ b/readme.md @@ -894,8 +894,8 @@ Note that only integers smaller than 4000 can be converted to Roman numberals. Humanizer can change numbers to Metric numerals using the `ToMetric` extension. The numbers 1, 1230 and 0.1 can be expressed in Metric numerals as follows: ```C# -1d.ToMetric() => "1" -1230d.ToMetric() => "1.23k" +1.ToMetric() => "1" +1230.ToMetric() => "1.23k" 0.1d.ToMetric() => "100m" ``` diff --git a/src/Humanizer.Tests.Shared/MetricNumeralTests.cs b/src/Humanizer.Tests.Shared/MetricNumeralTests.cs index b84c7f356..69bf9237f 100644 --- a/src/Humanizer.Tests.Shared/MetricNumeralTests.cs +++ b/src/Humanizer.Tests.Shared/MetricNumeralTests.cs @@ -110,12 +110,10 @@ public void TestAllSymbolsAsInt(int exponent) [InlineData("1000μ", 1E-3, false, true, null, MetricPrefix.Micro, MetricPrefix.Undefined)] [InlineData("1000", 1000, false, true, null, MetricPrefix.None, MetricPrefix.Undefined)] [InlineData("0.001m", 1E-6, false, true, null, MetricPrefix.Undefined, MetricPrefix.Milli)] - [InlineData("0m", 1E-6, false, true, 0, MetricPrefix.Undefined, MetricPrefix.Milli)] - [InlineData("0.01m", 1.234E-5, false, true, 2, MetricPrefix.Undefined, MetricPrefix.Milli)] + [InlineData("0m", 1E-6, false, true, 0, MetricPrefix.Undefined, MetricPrefix.Milli)] // Decimals and minPrefix options combined give value 0. Exponent remains. + [InlineData("0.01m", 1.234E-5, false, true, 2, MetricPrefix.Undefined, MetricPrefix.Milli)] [InlineData("12.34μ", 1.2345E-5, false, true, 2, MetricPrefix.Undefined, MetricPrefix.Micro)] [InlineData("0.01μ", 1.2345E-8, false, true, 2, MetricPrefix.Undefined, MetricPrefix.Micro)] - - public void ToMetric(string expected, double input, bool hasSpace, bool useSymbol, int? decimals, MetricPrefix maxPrefix, MetricPrefix minPrefix) { Assert.Equal(expected, input.ToMetric(hasSpace, useSymbol, decimals, maxPrefix, minPrefix)); diff --git a/src/Humanizer/MetricNumeralExtensions.cs b/src/Humanizer/MetricNumeralExtensions.cs index 9e37232a2..bab387b4c 100644 --- a/src/Humanizer/MetricNumeralExtensions.cs +++ b/src/Humanizer/MetricNumeralExtensions.cs @@ -1,8 +1,8 @@ -// Wrote by Alois de Gouvello https://github.com/aloisdg +// Written by Alois de Gouvello https://github.com/aloisdg with additions by Jonas Barkå https://github.com/JonasBarka. // The MIT License (MIT) -// Copyright (c) 2015 Alois de Gouvello +// Copyright (c) 2015-2019 Alois de Gouvello and each other contributor for their respective work. // Permission is hereby granted, free of charge, to any person obtaining a copy of // this software and associated documentation files (the "Software"), to deal in