/// <summary>Convert a long integer to a string with traditional binary prefix.</summary> /// <param name="n">the value to be converted</param> /// <param name="unit">The unit, e.g. "B" for bytes.</param> /// <param name="decimalPlaces">The number of decimal places.</param> /// <returns>a string with traditional binary prefix.</returns> public static string Long2String(long n, string unit, int decimalPlaces) { if (unit == null) { unit = string.Empty; } //take care a special case if (n == long.MinValue) { return("-8 " + StringUtils.TraditionalBinaryPrefix.Exa.symbol + unit); } StringBuilder b = new StringBuilder(); //take care negative numbers if (n < 0) { b.Append('-'); n = -n; } if (n < StringUtils.TraditionalBinaryPrefix.Kilo.value) { //no prefix b.Append(n); return((unit.IsEmpty() ? b : b.Append(" ").Append(unit)).ToString()); } else { //find traditional binary prefix int i = 0; for (; i < Values().Length&& n >= Values()[i].value; i++) { } StringUtils.TraditionalBinaryPrefix prefix = Values()[i - 1]; if ((n & prefix.bitMask) == 0) { //exact division b.Append(n >> prefix.bitShift); } else { string format = "%." + decimalPlaces + "f"; string s = Format(format, n / (double)prefix.value); //check a special rounding up case if (s.StartsWith("1024")) { prefix = Values()[i]; s = Format(format, n / (double)prefix.value); } b.Append(s); } return(b.Append(' ').Append(prefix.symbol).Append(unit).ToString()); } }
/// <exception cref="System.Exception"/> public virtual void TestTraditionalBinaryPrefix() { //test string2long(..) string[] symbol = new string[] { "k", "m", "g", "t", "p", "e" }; long m = 1024; foreach (string s in symbol) { Assert.Equal(0, StringUtils.TraditionalBinaryPrefix.String2long (0 + s)); Assert.Equal(m, StringUtils.TraditionalBinaryPrefix.String2long (1 + s)); m *= 1024; } Assert.Equal(0L, StringUtils.TraditionalBinaryPrefix.String2long ("0")); Assert.Equal(1024L, StringUtils.TraditionalBinaryPrefix.String2long ("1k")); Assert.Equal(-1024L, StringUtils.TraditionalBinaryPrefix.String2long ("-1k")); Assert.Equal(1259520L, StringUtils.TraditionalBinaryPrefix.String2long ("1230K")); Assert.Equal(-1259520L, StringUtils.TraditionalBinaryPrefix.String2long ("-1230K")); Assert.Equal(104857600L, StringUtils.TraditionalBinaryPrefix.String2long ("100m")); Assert.Equal(-104857600L, StringUtils.TraditionalBinaryPrefix.String2long ("-100M")); Assert.Equal(956703965184L, StringUtils.TraditionalBinaryPrefix.String2long ("891g")); Assert.Equal(-956703965184L, StringUtils.TraditionalBinaryPrefix.String2long ("-891G")); Assert.Equal(501377302265856L, StringUtils.TraditionalBinaryPrefix.String2long ("456t")); Assert.Equal(-501377302265856L, StringUtils.TraditionalBinaryPrefix.String2long ("-456T")); Assert.Equal(11258999068426240L, StringUtils.TraditionalBinaryPrefix.String2long ("10p")); Assert.Equal(-11258999068426240L, StringUtils.TraditionalBinaryPrefix.String2long ("-10P")); Assert.Equal(1152921504606846976L, StringUtils.TraditionalBinaryPrefix.String2long ("1e")); Assert.Equal(-1152921504606846976L, StringUtils.TraditionalBinaryPrefix.String2long ("-1E")); string tooLargeNumStr = "10e"; try { StringUtils.TraditionalBinaryPrefix.String2long(tooLargeNumStr); NUnit.Framework.Assert.Fail("Test passed for a number " + tooLargeNumStr + " too large" ); } catch (ArgumentException e) { Assert.Equal(tooLargeNumStr + " does not fit in a Long", e.Message ); } string tooSmallNumStr = "-10e"; try { StringUtils.TraditionalBinaryPrefix.String2long(tooSmallNumStr); NUnit.Framework.Assert.Fail("Test passed for a number " + tooSmallNumStr + " too small" ); } catch (ArgumentException e) { Assert.Equal(tooSmallNumStr + " does not fit in a Long", e.Message ); } string invalidFormatNumStr = "10kb"; char invalidPrefix = 'b'; try { StringUtils.TraditionalBinaryPrefix.String2long(invalidFormatNumStr); NUnit.Framework.Assert.Fail("Test passed for a number " + invalidFormatNumStr + " has invalid format" ); } catch (ArgumentException e) { Assert.Equal("Invalid size prefix '" + invalidPrefix + "' in '" + invalidFormatNumStr + "'. Allowed prefixes are k, m, g, t, p, e(case insensitive)" , e.Message); } //test long2string(..) Assert.Equal("0", StringUtils.TraditionalBinaryPrefix.Long2String (0, null, 2)); for (int decimalPlace = 0; decimalPlace < 2; decimalPlace++) { for (int n = 1; n < StringUtils.TraditionalBinaryPrefix.Kilo.value; n++) { Assert.Equal(n + string.Empty, StringUtils.TraditionalBinaryPrefix.Long2String (n, null, decimalPlace)); Assert.Equal(-n + string.Empty, StringUtils.TraditionalBinaryPrefix.Long2String (-n, null, decimalPlace)); } Assert.Equal("1 K", StringUtils.TraditionalBinaryPrefix.Long2String (1L << 10, null, decimalPlace)); Assert.Equal("-1 K", StringUtils.TraditionalBinaryPrefix.Long2String (-1L << 10, null, decimalPlace)); } Assert.Equal("8.00 E", StringUtils.TraditionalBinaryPrefix.Long2String (long.MaxValue, null, 2)); Assert.Equal("8.00 E", StringUtils.TraditionalBinaryPrefix.Long2String (long.MaxValue - 1, null, 2)); Assert.Equal("-8 E", StringUtils.TraditionalBinaryPrefix.Long2String (long.MinValue, null, 2)); Assert.Equal("-8.00 E", StringUtils.TraditionalBinaryPrefix.Long2String (long.MinValue + 1, null, 2)); string[] zeros = new string[] { " ", ".0 ", ".00 " }; for (int decimalPlace_1 = 0; decimalPlace_1 < zeros.Length; decimalPlace_1++) { string trailingZeros = zeros[decimalPlace_1]; for (int e = 11; e < long.Size - 1; e++) { StringUtils.TraditionalBinaryPrefix p = StringUtils.TraditionalBinaryPrefix.Values ()[e / 10 - 1]; { // n = 2^e long n = 1L << e; string expected = (n / p.value) + " " + p.symbol; Assert.Equal("n=" + n, expected, StringUtils.TraditionalBinaryPrefix.Long2String (n, null, 2)); } { // n = 2^e + 1 long n = (1L << e) + 1; string expected = (n / p.value) + trailingZeros + p.symbol; Assert.Equal("n=" + n, expected, StringUtils.TraditionalBinaryPrefix.Long2String (n, null, decimalPlace_1)); } { // n = 2^e - 1 long n = (1L << e) - 1; string expected = ((n + 1) / p.value) + trailingZeros + p.symbol; Assert.Equal("n=" + n, expected, StringUtils.TraditionalBinaryPrefix.Long2String (n, null, decimalPlace_1)); } } } Assert.Equal("1.50 K", StringUtils.TraditionalBinaryPrefix.Long2String (3L << 9, null, 2)); Assert.Equal("1.5 K", StringUtils.TraditionalBinaryPrefix.Long2String (3L << 9, null, 1)); Assert.Equal("1.50 M", StringUtils.TraditionalBinaryPrefix.Long2String (3L << 19, null, 2)); Assert.Equal("2 M", StringUtils.TraditionalBinaryPrefix.Long2String (3L << 19, null, 0)); Assert.Equal("3 G", StringUtils.TraditionalBinaryPrefix.Long2String (3L << 30, null, 2)); // test byteDesc(..) Assert.Equal("0 B", StringUtils.ByteDesc(0)); Assert.Equal("-100 B", StringUtils.ByteDesc(-100)); Assert.Equal("1 KB", StringUtils.ByteDesc(1024)); Assert.Equal("1.50 KB", StringUtils.ByteDesc(3L << 9)); Assert.Equal("1.50 MB", StringUtils.ByteDesc(3L << 19)); Assert.Equal("3 GB", StringUtils.ByteDesc(3L << 30)); // test formatPercent(..) Assert.Equal("10%", StringUtils.FormatPercent(0.1, 0)); Assert.Equal("10.0%", StringUtils.FormatPercent(0.1, 1)); Assert.Equal("10.00%", StringUtils.FormatPercent(0.1, 2)); Assert.Equal("1%", StringUtils.FormatPercent(0.00543, 0)); Assert.Equal("0.5%", StringUtils.FormatPercent(0.00543, 1)); Assert.Equal("0.54%", StringUtils.FormatPercent(0.00543, 2)); Assert.Equal("0.543%", StringUtils.FormatPercent(0.00543, 3)); Assert.Equal("0.5430%", StringUtils.FormatPercent(0.00543, 4)); }