String format numbers to millions, thousands with rounding

This should help, combined with one of the formatting techniques in the other questions you've linked to.

  internal long MaxThreeSignificantDigits(long x)
  {
     int i = (int)Math.Log10(x);
     i = Math.Max(0, i - 2);
     i = (int)Math.Pow(10, i);
     return x / i * i;
  }

EDIT:

OK, how about this?

 Console.WriteLine(SO30180672.FormatNumber(1));
 Console.WriteLine(SO30180672.FormatNumber(12));
 Console.WriteLine(SO30180672.FormatNumber(123));
 Console.WriteLine(SO30180672.FormatNumber(1234));
 Console.WriteLine(SO30180672.FormatNumber(12345));
 Console.WriteLine(SO30180672.FormatNumber(123456));
 Console.WriteLine(SO30180672.FormatNumber(1234567));
 Console.WriteLine(SO30180672.FormatNumber(12345678));
 Console.WriteLine(SO30180672.FormatNumber(123456789));

Following is partially copied from here: https://stackoverflow.com/a/23384710/253938

   internal class SO30180672
   {
      internal static string FormatNumber(long num)
      {
         num = MaxThreeSignificantDigits(num);

         if (num >= 100000000)
            return (num / 1000000D).ToString("0.#M");
         if (num >= 1000000)
            return (num / 1000000D).ToString("0.##M");
         if (num >= 100000)
            return (num / 1000D).ToString("0k");
         if (num >= 100000)
            return (num / 1000D).ToString("0.#k");
         if (num >= 1000)
            return (num / 1000D).ToString("0.##k");
         return num.ToString("#,0");
      }


      internal static long MaxThreeSignificantDigits(long x)
      {
         int i = (int)Math.Log10(x);
         i = Math.Max(0, i - 2);
         i = (int)Math.Pow(10, i);
         return x / i * i;
      }
   }

EDIT 2 - thank you very much to @Rhexis

   internal class SO30180672
   {
      internal static void RunTest()
      {
         Console.WriteLine(FormatNumber(1));
         Console.WriteLine(FormatNumber(10));
         Console.WriteLine(FormatNumber(100));
         Console.WriteLine(FormatNumber(1000));
         Console.WriteLine(FormatNumber(10000));
         Console.WriteLine(FormatNumber(100000));
         Console.WriteLine(FormatNumber(125000));
         Console.WriteLine(FormatNumber(125900));
         Console.WriteLine(FormatNumber(1000000));
         Console.WriteLine(FormatNumber(1250000));
         Console.WriteLine(FormatNumber(1258000));
         Console.WriteLine(FormatNumber(10000000));
         Console.WriteLine(FormatNumber(10500000));
         Console.WriteLine(FormatNumber(100000000));
         Console.WriteLine(FormatNumber(100100000));
      }

      private static string FormatNumber(long num)
      {
         // Ensure number has max 3 significant digits (no rounding up can happen)
         long i = (long)Math.Pow(10, (int)Math.Max(0, Math.Log10(num) - 2));
         num = num / i * i;

         if (num >= 1000000000)
            return (num / 1000000000D).ToString("0.##") + "B";
         if (num >= 1000000)
            return (num / 1000000D).ToString("0.##") + "M";
         if (num >= 1000)
            return (num / 1000D).ToString("0.##") + "K";

         return num.ToString("#,0");
      }
   }

This is my code with test outputs

1249            1.24K
12499           12.4K
124999          124K
1249999         1.24M
12499999        12.4M
124999999       124M
1249999999      1.24B

The code will output three digits at maximum.

    static string FormatNumber(uint n)
    {
        if (n < 1000)
            return n.ToString();

        if (n < 10000)
            return String.Format("{0:#,.##}K", n - 5);

        if (n < 100000)
            return String.Format("{0:#,.#}K", n - 50);

        if (n < 1000000)
            return String.Format("{0:#,.}K", n - 500);

        if (n < 10000000)
            return String.Format("{0:#,,.##}M", n - 5000);

        if (n < 100000000)
            return String.Format("{0:#,,.#}M", n - 50000);

        if (n < 1000000000)
            return String.Format("{0:#,,.}M", n - 500000);

        return String.Format("{0:#,,,.##}B", n - 5000000);
    }

Since the format essentially changes based on the range you'll most likely need some conditional formatting similar to below. I have only tested the sample set provided, so make sure this works for the full range of expected values.

class Program
{
    static void Main(String[] args)
    {
        Console.WriteLine(RoundAndFormat(1));
        Console.WriteLine(RoundAndFormat(10));
        Console.WriteLine(RoundAndFormat(100));
        Console.WriteLine(RoundAndFormat(1000));
        Console.WriteLine(RoundAndFormat(100000));
        Console.WriteLine(RoundAndFormat(125000));
        Console.WriteLine(RoundAndFormat(125900));
        Console.WriteLine(RoundAndFormat(1000000));
        Console.WriteLine(RoundAndFormat(1250000));
        Console.WriteLine(RoundAndFormat(1258000));
        Console.WriteLine(RoundAndFormat(10000000));
        Console.WriteLine(RoundAndFormat(10500000));
        Console.WriteLine(RoundAndFormat(100000000));
        Console.WriteLine(RoundAndFormat(100100000));

        Console.ReadLine();
    }

    public static String RoundAndFormat(Int32 value)
    {
        var result = String.Empty;
        var negative = value < 0;
        if (negative) value = value * -1;

        if (value < 1000)
        {
            result = value.ToString();
        }
        else if (value < 1000000)
        {
            result = RoundDown(value / 1000.0, 0) + "K";
        }
        else if (value < 100000000)
        {
            result = RoundDown(value / 1000000.0, 2) + "M";
        }
        else if (value < 10000000000)
        {
            result = RoundDown(value / 1000000.0, 0) + "M";
        }

        if (negative) return "-" + result;
        return result;
    }

    public static Double RoundDown(Double value, Int32 digits)
    {
        var pow = Math.Pow(10, digits);
        return Math.Truncate(value * pow) / pow;
    }

Tags:

C#

.Net

Currency