Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow int.ToString and Parse to support radixes other than base-10 and base-16 #50491

Closed
kingcean opened this issue Mar 31, 2021 · 5 comments
Closed
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Runtime
Milestone

Comments

@kingcean
Copy link

kingcean commented Mar 31, 2021

Background and Motivation

In ECMAScript (JS) world, we can parse an integer with a radix to specify its positional notation like following.

parseInt("120", 12);  // -> 168
parseInt("120", 10);  // -> 120

And we can also stringify a number (convert a number to string) with a radix (positional notation) like following.

(168).toString(12);  // -> "120"
(120).toString(10);  // -> "120"
(3.14159265).toString(30); // => "3.47d01bpf"

Currently now .NET only supports DEC and HEX but JS supports 2-36.

Proposed API

namespace System
{
    public struct Int32 : IComparable, IComparable<int>, IConvertible, IEquatable<int>, IFormattable
    {
+        public string ToString(int radix);
+        public static int Parse(string s, int radix);
+        public static int Parse(ReadOnlySpan<char> s, int radix);
+        public static bool TryParse(string s, int radix, out int result);
+        public static bool TryParse(ReadOnlySpan<char> s, int radix, out int result);
        // ... other fields and methods.
    }
    public struct Int64 : IComparable, IComparable<long>, IConvertible, IEquatable<long>, IFormattable
    {
+        public string ToString(int radix);
+        public static long Parse(string s, int radix);
+        public static long Parse(ReadOnlySpan<char> s, int radix);
+        public static bool TryParse(string s, int radix, out long result);
+        public static bool TryParse(ReadOnlySpan<char> s, int radix, out long result);
        // ... other fields and methods.
    }
    public struct Decimal : IComparable, IComparable<decimal>, IConvertible, IEquatable<decimal>, IFormattable
    {
+        public string ToString(int radix);
        // ... other fields and methods.
    }
    public struct Single : IComparable, IComparable<float>, IConvertible, IEquatable<float>, IFormattable
    {
+        public string ToString(int radix);
        // ... other fields and methods.
    }
    public struct Double : IComparable, IComparable<double>, IConvertible, IEquatable<double>, IFormattable
    {
+        public string ToString(int radix);
        // ... other fields and methods.
    }
}

Implementation

Following are some sample codes of the implementation to convert a number to a string with a specific radix.

Following are about parsing.

Usage Examples

int.Parse("120", 12);  // -> 168
int.Parse("120", 10);  // -> 120

168.ToString(12);  // -> "120"
120L.ToString(10);  // -> "120"
(3.14159265).ToString(30); // => "3.47d01bpf"
@kingcean kingcean added the api-suggestion Early API idea and discussion, it is NOT ready for implementation label Mar 31, 2021
@dotnet-issue-labeler
Copy link

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

@dotnet-issue-labeler dotnet-issue-labeler bot added the untriaged New issue has not been triaged by the area owner label Mar 31, 2021
@GrabYourPitchforks GrabYourPitchforks changed the title Positional notation Allow int.ToString and Parse to support radixes other than base-10 and base-16 Apr 8, 2021
@GrabYourPitchforks
Copy link
Member

I've updated the issue title to be a bit more descriptive. Can you describe your scenario a bit more? We already have inbox support for base10 and base16. Is base2 (binary) the most interesting radix for your workloads?

The main ECMAScript has a radix parameter is that historically, its parse routine tries to deduce the representation of the incoming number, but this can lead to incorrect guesses. For example, parseInt("0123") will [in older engines] see the leading '0' and treat the incoming string as octal instead of decimal. This necessitates passing an explicit 10 for the radix parameter for the common scenario of wanting the treat the incoming string as decimal-formatted.

.NET doesn't have this same behavior, since all numbers are emitted and parsed as decimal by default. There's no auto-detection of octal vs. hex vs. decimal in the parsing routines. So there has historically been no need to have a specialized radix parameter.

@kingcean
Copy link
Author

kingcean commented Apr 8, 2021

Sometimes I need use following radixes.

  • Base 2 for binary.
  • Base 36. It represents a number in the string with the shortest length.

@stephentoub
Copy link
Member

Just FYI, the Convert class already supports the ToString aspect of this for base 2, 8, 10, and 16, e.g.

Convert.ToString(12345, 2)

produces

"11000000111001"

@tannergooding
Copy link
Member

Closing in favor of #83619

While this API would be "more extensible" overall, it doesn't fit the current conventions and would be more work for less obvious overall benefits.

Convert.ToString does allow binary already as Stephen pointed out.

@ghost ghost locked as resolved and limited conversation to collaborators Apr 22, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Runtime
Projects
None yet
Development

No branches or pull requests

5 participants