Convert the following int argument into a string without using any native toString functionality.
public string integerToString(int integerPas
I am not truly convinced the concatenation operator +
calls ToString
, but if that is indeed true, you can avoid those two by doing something like the following:
if (a == 0) return "0";
/* Negative maxint doesn't have a corresponding positive value, so handle it
* as a special case. Thanks to @Daniel for pointing this out.
*/
if (a == 0x80000000) return "-2147483648";
List<char> l = new List<char>();
bool negative = false;
if (a < 0)
{
negative = true;
a *= -1;
}
while (a > 0)
{
l.Add('0' + (char)(a % 10));
a /= 10;
}
if (negative) l.Add('-');
l.Reverse();
return new String(l.ToArray());
Aiming for a shorter version, and one that uses Math.DivRem
:
string IntToString(int a)
{
if (a == int.MinValue)
return "-2147483648";
if (a < 0)
return "-" + IntToString(-a);
if (a == 0)
return "0";
var s = "";
do
{
int r;
a = Math.DivRem(a, 10, out r);
s = new string((char)(r + (int)'0'), 1) + s;
}
while (a > 0);
return s;
}
The use of the new string(..., 1)
constructor is just a way to satisfy the OP's requirement that ToString
not be called on anything.
The integer is processed from the least significant digit to the most significant. A single digit is computed used modulo 10 (%10) which is then added to the character value of '0'. This results in one of the characters '0', '1', ... , '9'.
The digits are pushed onto a stack because they have to be presented in the reverse order as they are processed (most significant digit to least significant digit). Doing it like this instead of repeatedly prepending the digits to a string could be more efficient but because the number of digits is quite low you would have to perform a benchmark to be sure.
Some extra processing is required to handle non-positive numbers.
public string IntToString(int a) {
if (a == 0)
return "0";
if (a == int.MinValue)
return "-2147483648";
var isNegative = false;
if (a < 0) {
a = -a;
isNegative = true;
}
var stack = new Stack<char>();
while (a != 0) {
var c = a%10 + '0';
stack.Push((char) c);
a /= 10;
}
if (isNegative)
stack.Push('-');
return new string(stack.ToArray());
}
My first version used a StringBuilder
to create the string from the array of characters but getting the string "out of the" StringBuilder
requires a call to method named ToString
. Obviously, this method does not do any int to string conversion which to me is what this question is about.
But to prove that you can create a string without calling ToString
I have switched to using a string
constructor which I also would assume to be more efficient compared to using a StringBuilder
.
And if ToString
in any form is prohibited you cannot use string concatenation as seen in the documentation for string.Concat:
The method concatenates arg0 and arg1by calling the parameterless ToString method of arg0 and arg1; it does not add any delimiters.
so executing s += '1'
will call '1'.ToString()
. But to me this isn't important. The important part is how you convert an int to a string.
This is the solution I always use:
public static string numberBaseChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static string IntToStringWithBase(int n, int b) {
return IntToStringWithBase(n, b, 1);
}
public static string IntToStringWithBase(int n, int b, int minDigits) {
if (minDigits < 1) minDigits = 1;
if (n == 0) return new string('0', minDigits);
string s = "";
if ((b < 2) || (b > numberBaseChars.Length)) return s;
bool neg = false;
if ((b == 10) && (n < 0)) { neg = true; n = -n; }
uint N = (uint)n;
uint B = (uint)b;
while ((N > 0) | (minDigits-- > 0)) {
s = numberBaseChars[(int)(N % B)] + s;
N /= B;
}
if (neg) s = "-" + s;
return s;
}
This looks quite complicated but has the following features: