Non-decimal radices/Convert: Difference between revisions

Content added Content deleted
(Updated D entries)
Line 523: Line 523:
=={{header|D}}==
=={{header|D}}==
===Using Standard Functions===
===Using Standard Functions===
<lang d>import std.stdio, std.conv, std.string;
<lang d>import std.stdio, std.conv, std.string, std.ascii;


void main() {
void main() {
"1abcd".to!int(16).writeln();
"1abcd".to!int(16).writeln;


toLower(60_272_032_366.to!string(36) ~ " " ~
writeln(60_272_032_366.to!string(36, LetterCase.lower), ' ',
591_458.to!string(36)).writeln();
591_458.to!string(36, LetterCase.lower));
}</lang>
}</lang>
{{out}}
{{out}}
<pre>109517
<pre>109517
rosetta code</pre>
rosetta code</pre>

===One Implementation===
===One Implementation===
<lang d>import std.stdio, std.array, std.ascii;
<lang d>import std.stdio, std.array, std.ascii;


enum string mDigits = "0123456789abcdefghijklmnopqrstuvwxyz";
immutable string mDigits = digits ~ lowercase;


ulong atoiRadix(in string str, in int radix=10, int* consumed=null) {
ulong atoiRadix(in string str, in uint radix=10, int* consumed=null)
nothrow {
static int dtoi(in char dc, in int radix) {
static int dtoi(in char dc, in uint radix) nothrow {
static int[immutable char] digit;
static int[immutable char] digit;
immutable char d = cast(char)toLower(dc);
immutable char d = dc.toLower;
if (digit.length == 0) // not init yet
if (digit.length == 0) // Not init yet.
foreach (i, c; mDigits)
foreach (i, c; mDigits)
digit[c] = i;
digit[c] = i;
Line 549: Line 551:
d in digit && digit[d] < radix)
d in digit && digit[d] < radix)
return digit[d];
return digit[d];
return int.min; // a negative for error.
return int.min; // A negative for error.
}
}


Line 556: Line 558:
for (; sp < str.length; sp++) {
for (; sp < str.length; sp++) {
immutable int d = dtoi(str[sp], radix);
immutable int d = dtoi(str[sp], radix);
if (d >= 0) // valid digit char
if (d >= 0) // Valid digit char.
result = radix * result + d;
result = radix * result + d;
else
else
break;
break;
}
}
if (sp != str.length) // some char in str not converted.
if (sp != str.length) // Some char in str not converted.
sp = -sp;
sp = -sp;
if (consumed !is null) // signal error if not positive.
if (consumed !is null) // Signal error if not positive.
*consumed = sp;
*consumed = sp;
return result;
return result;
}
}


string itoaRadix(ulong num, in int radix=10) pure nothrow
string itoaRadix(ulong num, in uint radix=10) pure nothrow
in {
in {
assert(radix > 1 && radix <= mDigits.length);
assert(radix > 1 && radix <= mDigits.length);
Line 574: Line 576:
string result;
string result;
while (num > 0) {
while (num > 0) {
//immutable int d = num % radix;
immutable uint d = num % radix;
immutable int d = cast(int)(num % radix);
result = mDigits[d] ~ result;
result = mDigits[d] ~ result;
num = (num - d) / radix;
num = (num - d) / radix;
Line 600: Line 601:
<pre>'1ABcdxyz???' (base 16) = 109517 Converted only: '1ABcd'
<pre>'1ABcdxyz???' (base 16) = 109517 Converted only: '1ABcd'
rosetta code</pre>
rosetta code</pre>

===Alternative Implementation===
===Alternative Implementation===
{{trans|Haskell}}
{{trans|Haskell}}
<lang d>import std.stdio, std.conv, std.algorithm, std.exception, std.ascii,
<lang d>import std.stdio, std.algorithm, std.ascii, std.array;
std.array;


alias Digits = ubyte[];
alias Digits = ubyte[];
Line 616: Line 617:
}
}


ulong fromBase(in Digits digits, in ubyte base) pure nothrow {
enum fromBase = (in Digits digits, in ubyte base) pure nothrow =>
return reduce!((n, k) => n * base + k)(0, digits);
reduce!((n, k) => n * base + k)(0UL, digits);
}


string fromDigits(in Digits digits) pure nothrow {
immutable myDigits = digits ~ lowercase;
return digits
.map!(d => cast(char)(d < 10 ? d + '0' : d + 'a' - 10))
.array;
}


Digits toDigits(in string number) pure /*nothrow*/ {
enum fromDigits = (in Digits digits) pure nothrow =>
digits.map!(d => myDigits[d]).array;
static ubyte convert(in dchar d) pure nothrow {

if (d.isDigit) return cast(typeof(return))(d - '0');
enum convert = (in dchar d) pure nothrow =>
if (d.isUpper) return cast(typeof(return))(d - 'A' + 10);
else return cast(typeof(return))(d - 'a' + 10);
cast(ubyte)(d.isDigit ? d - '0' : d.toLower - 'a' + 10);

}
return number.map!convert.array;
enum toDigits = (in string number) pure /*nothrow*/ =>
number.map!convert.array;
}


void main() {
void main() {