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; |
||
writeln(60_272_032_366.to!string(36, LetterCase.lower), ' ', |
|||
591_458.to!string(36) |
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; |
||
immutable string mDigits = digits ~ lowercase; |
|||
ulong atoiRadix(in string str, in |
ulong atoiRadix(in string str, in uint radix=10, int* consumed=null) |
||
nothrow { |
|||
static int dtoi(in char dc, in |
static int dtoi(in char dc, in uint radix) nothrow { |
||
static int[immutable char] digit; |
static int[immutable char] digit; |
||
immutable char d = |
immutable char d = dc.toLower; |
||
if (digit.length == 0) // |
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; // |
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) // |
if (d >= 0) // Valid digit char. |
||
result = radix * result + d; |
result = radix * result + d; |
||
else |
else |
||
break; |
break; |
||
} |
} |
||
if (sp != str.length) // |
if (sp != str.length) // Some char in str not converted. |
||
sp = -sp; |
sp = -sp; |
||
if (consumed !is null) // |
if (consumed !is null) // Signal error if not positive. |
||
*consumed = sp; |
*consumed = sp; |
||
return result; |
return result; |
||
} |
} |
||
string itoaRadix(ulong num, in |
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 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 |
<lang d>import std.stdio, std.algorithm, std.ascii, std.array; |
||
std.array; |
|||
alias Digits = ubyte[]; |
alias Digits = ubyte[]; |
||
Line 616: | Line 617: | ||
} |
} |
||
enum fromBase = (in Digits digits, in ubyte base) pure nothrow => |
|||
reduce!((n, k) => n * base + k)(0UL, digits); |
|||
} |
|||
immutable myDigits = digits ~ lowercase; |
|||
return digits |
|||
.map!(d => cast(char)(d < 10 ? d + '0' : d + 'a' - 10)) |
|||
.array; |
|||
} |
|||
enum fromDigits = (in Digits digits) pure nothrow => |
|||
digits.map!(d => myDigits[d]).array; |
|||
⚫ | |||
if (d.isDigit) return cast(typeof(return))(d - '0'); |
|||
⚫ | |||
if (d.isUpper) return cast(typeof(return))(d - 'A' + 10); |
|||
cast(ubyte)(d.isDigit ? d - '0' : d.toLower - 'a' + 10); |
|||
} |
|||
enum toDigits = (in string number) pure /*nothrow*/ => |
|||
number.map!convert.array; |
|||
} |
|||
void main() { |
void main() { |