How to format numbers like SO with C# ?
10, 5k ...
Thanks.
How to format numbers like SO with C# ?
10, 5k ...
Thanks.
Something like this:
string formatted;
if (num >= 1000) {
formatted = ((double)num / 1000.0).ToString("N1") + "k";
} else {
formatted = num.ToString("N0");
}
If the number is bigger than some threshold, divide it by 1000 and then format it to however many decimal places you need.
int input = 12392; // for example
if (input >= 10000)
{
double thousands = input/1000.0;
Console.WriteLine(string.Format("{0}K", thousands));
}
Like this: (EDIT: Tested)
static string FormatNumber(int num) {
if (num >= 100000)
return FormatNumber(num / 1000) + "K";
if (num >= 10000) {
return (num / 1000D).ToString("0.#") + "K";
}
return num.ToString("#,0");
}
Examples:
1
23
136
6,968
23.1K
133K
Note that this will give strange values for numbers >= 108.
For example, 12345678
becomes 12.3KK
.
You can crate a CustomFormater like this:
public class KiloFormatter: ICustomFormatter, IFormatProvider
{
public object GetFormat(Type formatType)
{
return (formatType == typeof(ICustomFormatter)) ? this : null;
}
public string Format(string format, object arg, IFormatProvider formatProvider)
{
if (format == null || !format.Trim().StartsWith("K")) {
if (arg is IFormattable) {
return ((IFormattable)arg).ToString(format, formatProvider);
}
return arg.ToString();
}
decimal value = Convert.ToDecimal(arg);
// Here's is where you format your number
if (value > 1000) {
return (value / 1000).ToString() + "k";
}
return value.ToString();
}
}
And use it like this:
String.Format(new KiloFormatter(), "{0:K}", 15600);
edit: Renamed CurrencyFormatter to KiloFormatter
The code below is tested up to int.MaxValue This is not the most beautiful code but is most efficient. But you can use it as:
123.KiloFormat(); 4332.KiloFormat(); 2332124.KiloFormat(); int.MaxValue.KiloFormat(); (int1 - int2 * int3).KiloFormat();
etc...
public static class Extensions
{
public static string KiloFormat(this int num)
{
if (num >= 100000000)
return (num / 1000000).ToString("#,0M");
if (num >= 10000000)
return (num / 1000000).ToString("0.#") + "M";
if (num >= 100000)
return (num / 1000).ToString("#,0K");
if (num >= 10000)
return (num / 1000).ToString("0.#") + "K";
return num.ToString("#,0");
}
}
I just wrote some to provide complete information
public static class SIPrefix
{
private static List<SIPrefixInfo> _SIPrefixInfoList = new
List<SIPrefixInfo>();
static SIPrefix()
{
_SIPrefixInfoList = new List<SIPrefixInfo>();
LoadSIPrefix();
}
public static List<SIPrefixInfo> SIPrefixInfoList
{
get
{
SIPrefixInfo[] siPrefixInfoList = new SIPrefixInfo[6];
_SIPrefixInfoList.CopyTo(siPrefixInfoList);
return siPrefixInfoList.ToList();
}
}
private static void LoadSIPrefix()
{
_SIPrefixInfoList.AddRange(new SIPrefixInfo[]{
new SIPrefixInfo() {Symbol = "Y", Prefix = "yotta", Example = 1000000000000000000000000.00M, ZeroLength = 24, ShortScaleName = "Septillion", LongScaleName = "Quadrillion"},
new SIPrefixInfo() {Symbol = "Z", Prefix = "zetta", Example = 1000000000000000000000M, ZeroLength = 21, ShortScaleName = "Sextillion", LongScaleName = "Trilliard"},
new SIPrefixInfo() {Symbol = "E", Prefix = "exa", Example = 1000000000000000000M, ZeroLength = 18, ShortScaleName = "Quintillion", LongScaleName = "Trillion"},
new SIPrefixInfo() {Symbol = "P", Prefix = "peta", Example = 1000000000000000M, ZeroLength = 15, ShortScaleName = "Quadrillion", LongScaleName = "Billiard"},
new SIPrefixInfo() {Symbol = "T", Prefix = "tera", Example = 1000000000000M, ZeroLength = 12, ShortScaleName = "Trillion", LongScaleName = "Billion"},
new SIPrefixInfo() {Symbol = "G", Prefix = "giga", Example = 1000000000M, ZeroLength = 9, ShortScaleName = "Billion", LongScaleName = "Milliard"},
new SIPrefixInfo() {Symbol = "M", Prefix = "mega", Example = 1000000M, ZeroLength = 6, ShortScaleName = "Million", LongScaleName = "Million"},
new SIPrefixInfo() {Symbol = "K", Prefix = "kilo", Example = 1000M, ZeroLength = 3, ShortScaleName = "Thousand", LongScaleName = "Thousand"},
new SIPrefixInfo() {Symbol = "h", Prefix = "hecto", Example = 100M, ZeroLength = 2, ShortScaleName = "Hundred", LongScaleName = "Hundred"},
new SIPrefixInfo() {Symbol = "da", Prefix = "deca", Example = 10M, ZeroLength = 1, ShortScaleName = "Ten", LongScaleName = "Ten"},
new SIPrefixInfo() {Symbol = "", Prefix = "", Example = 1M, ZeroLength = 0, ShortScaleName = "One", LongScaleName = "One"},
});
}
public static SIPrefixInfo GetInfo(long amount, int decimals)
{
return GetInfo(Convert.ToDecimal(amount), decimals);
}
public static SIPrefixInfo GetInfo(decimal amount, int decimals)
{
SIPrefixInfo siPrefixInfo = null;
decimal amountToTest = Math.Abs(amount);
var amountLength = amountToTest.ToString("0").Length;
if(amountLength < 3)
{
siPrefixInfo = _SIPrefixInfoList.Find(i => i.ZeroLength == amountLength).Clone() as SIPrefixInfo;
siPrefixInfo.AmountWithPrefix = Math.Round(amount, decimals).ToString();
return siPrefixInfo;
}
siPrefixInfo = _SIPrefixInfoList.Find(i => amountToTest > i.Example).Clone() as SIPrefixInfo;
siPrefixInfo.AmountWithPrefix = Math.Round(
amountToTest / Convert.ToDecimal(siPrefixInfo.Example), decimals).ToString()
+ siPrefixInfo.Symbol;
return siPrefixInfo;
}
}
public class SIPrefixInfo : ICloneable
{
public string Symbol { get; set; }
public decimal Example { get; set; }
public string Prefix { get; set; }
public int ZeroLength { get; set; }
public string ShortScaleName { get; set; }
public string LongScaleName { get; set; }
public string AmountWithPrefix { get; set; }
public object Clone()
{
return new SIPrefixInfo()
{
Example = this.Example,
LongScaleName = this.LongScaleName,
ShortScaleName = this.ShortScaleName,
Symbol = this.Symbol,
Prefix = this.Prefix,
ZeroLength = this.ZeroLength
};
}
}
Use:
var amountInfo = SIPrefix.GetInfo(10250, 2);
var amountInfo2 = SIPrefix.GetInfo(2500000, 0);
amountInfo.AmountWithPrefix // 10.25K
amountInfo2.AmountWithPrefix // 2M