Skip to content

Commit 7077c4e

Browse files
committed
[GH Usage] Fixed ToKiloFormat
1 parent fa90e58 commit 7077c4e

2 files changed

Lines changed: 93 additions & 37 deletions

File tree

src/NuGetGallery/Extensions/NumberExtensions.cs

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -70,28 +70,42 @@ public static string ToUserFriendlyBytesLabel(this long bytes)
7070
}
7171

7272
/// <summary>
73-
/// Format the number to a 3 digit representation plus a letter to represent the scale (K for kilo, M for mega, or B for billion)
73+
/// Format the number to a 1 decimal precision plus a letter to represent the scale (K for kilo, M for mega, or B for billion)
7474
/// </summary>
75-
/// <param name="number"></param>
76-
/// <returns></returns>
75+
/// <param name="number">The number to format</param>
76+
/// <returns>String representation of the formatted number</returns>
7777
public static string ToKiloFormat(this int number)
7878
{
79-
var thresholds = new[]
79+
bool isNegative = number < 0;
80+
if (isNegative)
81+
{
82+
number *= -1;
83+
}
84+
85+
if (number < 1000)
86+
{
87+
return (isNegative ? "-" : "") + number.ToString();
88+
}
89+
90+
var powers = new[]
8091
{
81-
new { Threshold = 1_000_000_000, Transform = new Func<int, float>((x) => x / 1_000_000_000f), Format = "{0:F3}B", Trim = true },
82-
new { Threshold = 100_000_000, Transform = new Func<int, float>((x) => x / 1_000_000), Format = "{0:F0}M", Trim = false},
83-
new { Threshold = 10_000_000, Transform = new Func<int, float>((x) => x / 1_000_000f), Format = "{0:F2}M", Trim = true},
84-
new { Threshold = 1_000_000, Transform = new Func<int, float>((x) => x / 1_000_000f), Format = "{0:F3}M", Trim = true},
85-
new { Threshold = 100_000, Transform = new Func<int, float>((x) => x / 1_000), Format = "{0}K", Trim = false},
86-
new { Threshold = 10_000, Transform = new Func<int, float>((x) => x / 1_000f), Format = "{0:F2}K", Trim = true},
87-
new { Threshold = 1_000, Transform = new Func<int, float>((x) => x / 1_000f), Format = "{0:F3}K", Trim = true},
88-
new { Threshold = int.MinValue, Transform = new Func<int, float>((x) => x), Format = "{0}", Trim = false}
92+
new { Pow = 9 , Value = 1_000_000_000f, Unit = 'B'},
93+
new { Pow = 6 , Value = 1_000_000f , Unit = 'M'},
94+
new { Pow = 3 , Value = 1_000f , Unit = 'K'},
95+
new { Pow = 0 , Value = 1f , Unit = '\0'}
8996
};
9097

91-
var elem = thresholds.First(d => number >= d.Threshold);
92-
var strFormat = string.Format(elem.Format, elem.Transform(number));
98+
var multiplier = powers.First(x => number.ToString().Length > x.Pow);
99+
var simplifiedNumber = (number / multiplier.Value);
100+
var roundValue = (int)float.Parse(string.Format("{0:F1}", simplifiedNumber));
101+
102+
// This is used in some cases to get the right power with its unit (e.g: 999_999_000 is rounded to 1.0B)
103+
if (roundValue > simplifiedNumber)
104+
{
105+
return (roundValue * (int)multiplier.Value * (isNegative ? -1 : 1)).ToKiloFormat();
106+
}
93107

94-
return elem.Trim ? strFormat.Remove(4, 1) : strFormat;
108+
return (isNegative ? "-" : "") + string.Format("{0:F1}", simplifiedNumber) + multiplier.Unit;
95109
}
96110
}
97111
}

tests/NuGetGallery.Facts/Extensions/NumberExtensionsFacts.cs

Lines changed: 64 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -33,28 +33,70 @@ public void FormatsUsingExpectedUnit(long bytes, string expected)
3333
public class TheToKiloFormatMethod
3434
{
3535
[Theory]
36-
[InlineData(1, "1")]
37-
[InlineData(999, "999")]
38-
[InlineData(1000, "1.00K")]
39-
[InlineData(1990, "1.99K")]
40-
[InlineData(1999, "1.99K")]
41-
[InlineData(9990, "9.99K")]
42-
[InlineData(9999, "9.99K")]
43-
[InlineData(10_000, "10.0K")]
44-
[InlineData(10_990, "10.9K")]
45-
[InlineData(99_990, "99.9K")]
46-
[InlineData(100_000, "100K")]
47-
[InlineData(100_990, "100K")]
48-
[InlineData(100_999, "100K")]
49-
[InlineData(999_000, "999K")]
50-
[InlineData(999_999, "999K")]
51-
[InlineData(1_000_000, "1.00M")]
52-
[InlineData(1_999_000, "1.99M")]
53-
[InlineData(99_990_000, "99.9M")]
54-
[InlineData(100_990_000, "100M")]
55-
[InlineData(999_990_000, "999M")]
56-
[InlineData(1_000_000_000, "1.00B")]
57-
[InlineData(1_999_000_000, "1.99B")]
36+
[InlineData(1, "1")]
37+
[InlineData(999, "999")]
38+
[InlineData(1000, "1.0K")]
39+
[InlineData(1450, "1.5K")]
40+
[InlineData(1900, "1.9K")]
41+
[InlineData(1990, "2.0K")]
42+
[InlineData(1999, "2.0K")]
43+
[InlineData(9940, "9.9K")]
44+
[InlineData(9949, "9.9K")]
45+
[InlineData(9950, "10.0K")]
46+
[InlineData(9999, "10.0K")]
47+
[InlineData(10_000, "10.0K")]
48+
[InlineData(99_949, "99.9K")]
49+
[InlineData(99_950, "100.0K")]
50+
[InlineData(99_990, "100.0K")]
51+
[InlineData(100_000, "100.0K")]
52+
[InlineData(100_990, "101.0K")]
53+
[InlineData(100_999, "101.0K")]
54+
[InlineData(999_000, "999.0K")]
55+
[InlineData(999_999, "1.0M")]
56+
[InlineData(1_000_000, "1.0M")]
57+
[InlineData(9_949_000, "9.9M")]
58+
[InlineData(9_950_000, "10.0M")]
59+
[InlineData(9_999_000, "10.0M")]
60+
[InlineData(99_990_000, "100.0M")]
61+
[InlineData(100_940_000, "100.9M")]
62+
[InlineData(100_949_000, "100.9M")]
63+
[InlineData(100_950_000, "101.0M")]
64+
[InlineData(100_990_000, "101.0M")]
65+
[InlineData(999_990_000, "1.0B")]
66+
[InlineData(1_000_000_000, "1.0B")]
67+
[InlineData(1_999_000_000, "2.0B")]
68+
[InlineData(-1, "-1")]
69+
[InlineData(-999, "-999")]
70+
[InlineData(-1000, "-1.0K")]
71+
[InlineData(-1450, "-1.5K")]
72+
[InlineData(-1900, "-1.9K")]
73+
[InlineData(-1990, "-2.0K")]
74+
[InlineData(-1999, "-2.0K")]
75+
[InlineData(-9940, "-9.9K")]
76+
[InlineData(-9949, "-9.9K")]
77+
[InlineData(-9950, "-10.0K")]
78+
[InlineData(-9999, "-10.0K")]
79+
[InlineData(-10_000, "-10.0K")]
80+
[InlineData(-99_949, "-99.9K")]
81+
[InlineData(-99_950, "-100.0K")]
82+
[InlineData(-99_990, "-100.0K")]
83+
[InlineData(-100_000, "-100.0K")]
84+
[InlineData(-100_990, "-101.0K")]
85+
[InlineData(-100_999, "-101.0K")]
86+
[InlineData(-999_000, "-999.0K")]
87+
[InlineData(-999_999, "-1.0M")]
88+
[InlineData(-1_000_000, "-1.0M")]
89+
[InlineData(-9_949_000, "-9.9M")]
90+
[InlineData(-9_950_000, "-10.0M")]
91+
[InlineData(-9_999_000, "-10.0M")]
92+
[InlineData(-99_990_000, "-100.0M")]
93+
[InlineData(-100_940_000, "-100.9M")]
94+
[InlineData(-100_949_000, "-100.9M")]
95+
[InlineData(-100_950_000, "-101.0M")]
96+
[InlineData(-100_990_000, "-101.0M")]
97+
[InlineData(-999_990_000, "-1.0B")]
98+
[InlineData(-1_000_000_000, "-1.0B")]
99+
[InlineData(-1_999_000_000, "-2.0B")]
58100
public void FormatsUsingExpectedUnit(int number, string expected)
59101
{
60102
var actual = NumberExtensions.ToKiloFormat(number);

0 commit comments

Comments
 (0)