Search code examples
c#stringformattingformatnumber-formatting

C# convert formatted string (31.2k) back to number (31240)


Let's say I have this code:

int i = 31240;
string Number = ((double)i / 1000).ToString("0.#k");

I get this result as a string for Number: 31,2k

And now, I wanna do the exact opposite, that is to take this string "31,2k" and take it back to 31240 or even to 31200, but I don't know how to do... Any idea?


Someone said that was impossible. BUT Finally I found the perfect way to achieve my goal. I post the solution for those who could be willing to know. The use is simple, and it allows to make 2 kind of conversions:

  • Thousands, Example: 45831 <=> 45,8k <=> 45831
  • Millions, Example: 123852376 <=> 123,5m <=> 123852376

Solution

  • Here is the solution I went through:

    public class StringFromInt
    {
        public enum FormatStyle
        {
            Kilo = 1000,
            Mega = 1000000
        }
        public int Number;
        public FormatStyle Format
        {
            get
            {
                switch (LimitValueBeforeConversion)
                {
                    case 1000: return FormatStyle.Kilo;
                    case 1000000: return FormatStyle.Mega;
                    default:
                        throw new NotImplementedException("You must implement the code for this kind of value");
                }
            }
            set
            {
                if (value == FormatStyle.Kilo)
                {
                    LimitValueBeforeConversion = 1000;
                }
                else if (value == FormatStyle.Mega)
                {
                    LimitValueBeforeConversion = 1000000;
                }
            }
        }
        public int LimitValueBeforeConversion
        { get; set; }
        public static implicit operator int(StringFromInt s)
        {
            return s.Number;
        }
        public static implicit operator StringFromInt(int number)
        {
            StringFromInt s = new StringFromInt(number);
            return s;
        }
    
        #region Constructors
        public StringFromInt(int number, FormatStyle format)
        {
            this.Number = number;
            Format = format;
        }
        public StringFromInt(int number)
            : this(number, FormatStyle.Kilo)
        {
            if (number >= 1000000)
            {
                this.Format = FormatStyle.Mega;
            }
        }
        #endregion
    
        public override string ToString()
        {
            if (Number >= LimitValueBeforeConversion)
            {
                string formatString = "0.#k";
                switch (Format)
                {
                    case FormatStyle.Kilo:
                        formatString = "0.#k";
                        break;
                    case FormatStyle.Mega:
                        formatString = "0.#m";
                        break;
                    default:
                        throw new NotImplementedException("You must implement the code for this kind of value");
                }
                return ((double)Number / LimitValueBeforeConversion).ToString(formatString);
            }
            else
            {
                return Number.ToString();
            }
        }
    }
    

    And here is a test program:

    class Program
    {
        static void Main(string[] args)
        {
            int i = 31240;
    
            string StringRepresentation = ((double)i / 1000).ToString("0.#k");
            int resultBackWithParse = int.Parse(StringRepresentation.Substring(0, StringRepresentation.Length - 1).Replace(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator, string.Empty)) * 100;
            Console.WriteLine("Base number: " + i.ToString());
            Console.WriteLine(new string('-', 35));
            Console.WriteLine("String representation: " + StringRepresentation);
            Console.WriteLine("Int representation With Int.Parse: " + resultBackWithParse.ToString());
            Console.WriteLine();
            StringFromInt MySolutionNumber = i;
            int resultBackWithStringFromInt = MySolutionNumber;
            Console.WriteLine("String representation With StringFromInt: " + MySolutionNumber.ToString());
            Console.WriteLine("Int representation With StringFromInt: " + resultBackWithStringFromInt);
    
            Console.WriteLine(new string('=', 35) + "\n");
            i = 123456789;
            StringFromInt MyNumber = 123456789;
            int resultBack = MyNumber;
            Console.WriteLine("Base number: " + i.ToString());
            Console.WriteLine(new string('-', 35));
            Console.WriteLine("String representation With StringFromInt: " + MyNumber);
            Console.WriteLine("Int representation With StringFromInt: " + resultBack);
    
            Console.ReadKey(true);
        }
    }
    

    As you can notice, there is no need to use the "new" initializer, I mean no need to do:

    StringFromInt Number = new StringFromInt(YourNumber)
    

    Thanks to the implicit operator, you can do:

    StringFromInt Number = YourNumber
    

    I don't know, but I think it's a good beginning, what do you think?

    Anyway, I managed to do what I wanted, so for people who thought it couldn't be done, you see, that's possible :-)

    Obviously this can be improved: this version works for thousands and millions only.

    Greetings