Convert.ToString() Base Limitations

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Jonathan Wood

    #1

    Convert.ToString() Base Limitations

    Does anyone know why the toBase argument in Convert.ToStrin g() is limited to
    2, 8, 10, or 16? It takes virtually the same code to support all base values
    from 2 to 36.

    And can anyone tell me if the .NET library provides the means to convert a
    number to a string using base-36?

    Thanks.

    --
    Jonathan Wood
    SoftCircuits Programming



  • Jon Skeet [C# MVP]

    #2
    Re: Convert.ToStrin g() Base Limitations

    Jonathan Wood <jwood@softcirc uits.comwrote:
    Does anyone know why the toBase argument in Convert.ToStrin g() is limited to
    2, 8, 10, or 16? It takes virtually the same code to support all base values
    from 2 to 36.
    >
    And can anyone tell me if the .NET library provides the means to convert a
    number to a string using base-36?
    I haven't seen such a call anywhere in the library, but it wouldn't be
    hard to write an arbitrary conversion which either took just a base and
    used the alphabet, or took a character array or string where each
    character is a "digit" to use in the output, where the base is just the
    length of the array/string.

    If you want, I could try to put that into my MiscUtil library over the
    weekend...

    --
    Jon Skeet - <skeet@pobox.co m>
    http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
    If replying to the group, please do not mail me too

    Comment

    • Jonathan Wood

      #3
      Re: Convert.ToStrin g() Base Limitations

      Like I indicated before, the same code that generates base-2 or base-10
      strings can also generate base-36 so I really don't understand the
      limitation. Writing my own simply duplicates that code.

      At any rate, I did write my own. I'm a long time programmer but new to C# so
      if anyone sees anything I could've done better, I'm open to constructive
      criticism.

      Thanks.

      static string _alphaDigits = "0123456789ABCD EFGHIJKLMNOPQRS TUVWXYZ";

      string UIntToString(UI nt32 value, UInt32 toBase)
      {
      string result = "";

      do
      {
      UInt32 digitValue = (value % toBase);
      result += _alphaDigits[(int)digitValue];
      value /= toBase;
      } while (value != 0);
      result = ReverseString(r esult);
      return result;
      }

      UInt32 StringToUInt(st ring s, UInt32 toBase)
      {
      UInt32 result = 0;

      for (int i = 0; i < s.Length; i++)
      {
      result *= toBase;
      result += (UInt32)_alphaD igits.IndexOf(s[i]);
      }
      return result;
      }

      string ReverseString(s tring s)
      {
      string result = "";

      for (int i = 0; i < s.Length; i++)
      result = s.Substring(i, 1) + result;
      return result;
      }

      --
      Jonathan Wood
      SoftCircuits Programming


      "Jon Skeet [C# MVP]" <skeet@pobox.co mwrote in message
      news:MPG.1fc6cb 4965fdbd1498d61 b@msnews.micros oft.com...
      Jonathan Wood <jwood@softcirc uits.comwrote:
      >Does anyone know why the toBase argument in Convert.ToStrin g() is limited
      >to
      >2, 8, 10, or 16? It takes virtually the same code to support all base
      >values
      >from 2 to 36.
      >>
      >And can anyone tell me if the .NET library provides the means to convert
      >a
      >number to a string using base-36?
      >
      I haven't seen such a call anywhere in the library, but it wouldn't be
      hard to write an arbitrary conversion which either took just a base and
      used the alphabet, or took a character array or string where each
      character is a "digit" to use in the output, where the base is just the
      length of the array/string.
      >
      If you want, I could try to put that into my MiscUtil library over the
      weekend...
      >
      --
      Jon Skeet - <skeet@pobox.co m>
      http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
      If replying to the group, please do not mail me too

      Comment

      • Jon Skeet [C# MVP]

        #4
        Re: Convert.ToStrin g() Base Limitations

        Jonathan Wood <jwood@softcirc uits.comwrote:
        Like I indicated before, the same code that generates base-2 or base-10
        strings can also generate base-36 so I really don't understand the
        limitation. Writing my own simply duplicates that code.
        >
        At any rate, I did write my own. I'm a long time programmer but new to C# so
        if anyone sees anything I could've done better, I'm open to constructive
        criticism.
        >
        Thanks.
        >
        static string _alphaDigits = "0123456789ABCD EFGHIJKLMNOPQRS TUVWXYZ";
        Firstly, I'd make that a const string, and give it an appropriate
        conventional name:

        const sting AlphaDigits = "0123456789ABCD EFGHIJKLMNOPQRS TUVWXYZ";
        string UIntToString(UI nt32 value, UInt32 toBase)
        I'd make that

        static string UInt32ToString( uint value, uint toBase)

        Making the type name the .NET name makes it easier to understand from
        other languages, but using the C# aliases gives colouring in Visual
        Studio.
        {
        string result = "";
        >
        do
        {
        UInt32 digitValue = (value % toBase);
        result += _alphaDigits[(int)digitValue];
        value /= toBase;
        } while (value != 0);
        result = ReverseString(r esult);
        return result;
        }
        This is a bad way of building up a string - use StringBuilder instead.
        See http://www.pobox.com/~skeet/csharp/stringbuilder.html
        In this particular case you'll never actually have much performance
        penalty, but it's a good idea to get into good habits. It also means
        you can reverse the contents of the StringBuilder in place.
        UInt32 StringToUInt(st ring s, UInt32 toBase)
        {
        UInt32 result = 0;
        >
        for (int i = 0; i < s.Length; i++)
        {
        result *= toBase;
        result += (UInt32)_alphaD igits.IndexOf(s[i]);
        }
        return result;
        }
        Other than the lack of error checking, this seems reasonable. (With the
        same suggestions about naming, making it static etc)
        >
        string ReverseString(s tring s)
        {
        string result = "";
        >
        for (int i = 0; i < s.Length; i++)
        result = s.Substring(i, 1) + result;
        return result;
        }
        Again, I'd use StringBuilder - but I'd probably write it as:

        static string ReverseString (string s)
        {
        return Reverse(new StringBuilder(s )).ToString();
        }

        // Note: returns the StringBuilder reference passed in for
        // ease of method chaining - the contents are reversed
        // in-place.
        static StringBuilder Reverse (StringBuilder builder)
        {
        int lowIndex = 0;
        int highIndex = builder.Length-1;

        while (lowIndex <= highIndex)
        {
        char c = builder[lowIndex];
        builder[lowIndex] = builder[highIndex];
        builder[highIndex] = c;
        lowIndex++;
        highIndex--;
        }
        }

        All of that is completely untested, by the way...

        --
        Jon Skeet - <skeet@pobox.co m>
        http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
        If replying to the group, please do not mail me too

        Comment

        • Jonathan Wood

          #5
          Re: Convert.ToStrin g() Base Limitations

          Thanks for the feedback. I've printed your post and will go over it
          carefully later.

          --
          Jonathan Wood
          SoftCircuits Programming



          "Jon Skeet [C# MVP]" <skeet@pobox.co mwrote in message
          news:MPG.1fc6f5 5eadb2c1bc98d62 0@msnews.micros oft.com...
          Jonathan Wood <jwood@softcirc uits.comwrote:
          >Like I indicated before, the same code that generates base-2 or base-10
          >strings can also generate base-36 so I really don't understand the
          >limitation. Writing my own simply duplicates that code.
          >>
          >At any rate, I did write my own. I'm a long time programmer but new to C#
          >so
          >if anyone sees anything I could've done better, I'm open to constructive
          >criticism.
          >>
          >Thanks.
          >>
          >static string _alphaDigits = "0123456789ABCD EFGHIJKLMNOPQRS TUVWXYZ";
          >
          Firstly, I'd make that a const string, and give it an appropriate
          conventional name:
          >
          const sting AlphaDigits = "0123456789ABCD EFGHIJKLMNOPQRS TUVWXYZ";
          >
          >string UIntToString(UI nt32 value, UInt32 toBase)
          >
          I'd make that
          >
          static string UInt32ToString( uint value, uint toBase)
          >
          Making the type name the .NET name makes it easier to understand from
          other languages, but using the C# aliases gives colouring in Visual
          Studio.
          >
          >{
          > string result = "";
          >>
          > do
          > {
          > UInt32 digitValue = (value % toBase);
          > result += _alphaDigits[(int)digitValue];
          > value /= toBase;
          > } while (value != 0);
          > result = ReverseString(r esult);
          > return result;
          >}
          >
          This is a bad way of building up a string - use StringBuilder instead.
          See http://www.pobox.com/~skeet/csharp/stringbuilder.html
          In this particular case you'll never actually have much performance
          penalty, but it's a good idea to get into good habits. It also means
          you can reverse the contents of the StringBuilder in place.
          >
          >UInt32 StringToUInt(st ring s, UInt32 toBase)
          >{
          > UInt32 result = 0;
          >>
          > for (int i = 0; i < s.Length; i++)
          > {
          > result *= toBase;
          > result += (UInt32)_alphaD igits.IndexOf(s[i]);
          > }
          > return result;
          >}
          >
          Other than the lack of error checking, this seems reasonable. (With the
          same suggestions about naming, making it static etc)
          >
          >>
          >string ReverseString(s tring s)
          >{
          > string result = "";
          >>
          > for (int i = 0; i < s.Length; i++)
          > result = s.Substring(i, 1) + result;
          > return result;
          >}
          >
          Again, I'd use StringBuilder - but I'd probably write it as:
          >
          static string ReverseString (string s)
          {
          return Reverse(new StringBuilder(s )).ToString();
          }
          >
          // Note: returns the StringBuilder reference passed in for
          // ease of method chaining - the contents are reversed
          // in-place.
          static StringBuilder Reverse (StringBuilder builder)
          {
          int lowIndex = 0;
          int highIndex = builder.Length-1;
          >
          while (lowIndex <= highIndex)
          {
          char c = builder[lowIndex];
          builder[lowIndex] = builder[highIndex];
          builder[highIndex] = c;
          lowIndex++;
          highIndex--;
          }
          }
          >
          All of that is completely untested, by the way...
          >
          --
          Jon Skeet - <skeet@pobox.co m>
          http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
          If replying to the group, please do not mail me too

          Comment

          Working...