Non-decimal radices/Convert: Difference between revisions

Add source for Rust
m (→‎{{header|Wren}}: Library name change.)
(Add source for Rust)
Line 535:
char *to_base(int64_t num, int base)
{
char *tbl = "0123456789abcdefghijklmnopqrstuvwxyz";
char buf[66] = {'\0'};
char *out;
uint64_t n;
int i, len = 0, neg = 0;
if (base > 36) {
fprintf(stderr, "base %d too large\n", base);
return 0;
}
 
/* safe against most negative integer */
n = ((neg = num < 0)) ? (~num) + 1 : num;
 
do { buf[len++] = tbl[n % base]; } while(n /= base);
 
out = malloc(len + neg + 1);
for (i = neg; len > 0; i++) out[i] = buf[--len];
if (neg) out[0] = '-';
 
return out;
}
 
long from_base(const char *num_str, int base)
{
char *endptr;
/* there is also strtoul() for parsing into an unsigned long */
/* in C99, there is also strtoll() and strtoull() for parsing into long long and
* unsigned long long, respectively */
int result = strtol(num_str, &endptr, base);
return result;
}
 
int main()
{
int64_t x;
x = ~(1LL << 63) + 1;
printf("%lld in base 2: %s\n", x, to_base(x, 2));
x = 383;
printf("%lld in base 16: %s\n", x, to_base(x, 16));
return 0;
}</lang>output
<pre>-9223372036854775808 in base 2: -1000000000000000000000000000000000000000000000000000000000000000
Line 749:
ClassMethod ConvertBase10ToN(pNum As %Integer = "", pBase As %Integer = "", pBaseStr As %String = "", pPos As %Integer = 0) As %String
{
If pNum=0 Quit ""
Set str=..ConvertBase10ToN(pNum\pBase, pBase, pBaseStr, pPos+1)
Quit str_$Extract(pBaseStr, pNum#pBase+1)
}
 
ClassMethod ConvertBaseNTo10(pStr As %String = "", pBase As %Integer = "", pBaseStr As %String = "", pPos As %Integer = 0) As %Integer
{
If pStr="" Quit 0
Set num=..ConvertBaseNTo10($Extract(pStr, 1, *-1), pBase, pBaseStr, pPos+1)
Set dec=$Find(pBaseStr, $Extract(pStr, *))-2
Quit num+(dec*(pBase**pPos))
}
 
ClassMethod ConvertBase(pStr As %String = "", pFrom As %Integer = 10, pTo As %Integer = 10, pBaseStr As %String = "", pLen As %Integer = 0) As %String
{
// some initialisation
If pBaseStr="" Set pBaseStr="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
// check input values
If pFrom=10 Set pStr=$Number(pStr, "i", 0) If pStr="" Quit ""
Set pFrom=$Number(pFrom, "i", 2, 94) If pFrom="" Quit ""
Set pTo=$Number(pTo, "i", 2, 94) If pTo="" Quit ""
Set pLen=$Number(pLen, "i", 0, 32) If pLen="" Quit ""
// does base number exceed base string?
If pFrom>$Length(pBaseStr) Quit ""
If pTo>$Length(pBaseStr) Quit ""
// allow for upper/lowercase values
If pTo=10 {
If $Match(pStr, "^[0-9a-z]+$"), $Match($Extract(pBaseStr, 1, pFrom), "^[0-9A-Z]+$") {
Set pStr=$ZConvert(pStr, "U")
}
}
If $Match(pStr, "^[0-9A-Z]+$"), $Match($Extract(pBaseStr, 1, pFrom), "^[0-9a-z]+$") {
Set pStr=$ZConvert(pStr, "L")
}
}
}
// do the conversion
If pFrom=pTo {
Set pStr=pStr
} ElseIf pFrom=10 {
Set pStr=..ConvertBase10ToN($Select(pStr=0: "", 1: pStr), pTo, pBaseStr)
} ElseIf pTo=10 {
Set pStr=..ConvertBaseNTo10(pStr, pFrom, pBaseStr)
} Else {
Set pStr=..ConvertBase10ToN(..ConvertBaseNTo10(pStr, pFrom, pBaseStr), pTo, pBaseStr)
}
// return value
If pLen=0 Quit pStr
If pTo'=10 Quit ..PadStr(pStr, pLen, $Extract(pBaseStr))
Quit ..PadStr(pStr, pLen)
}
 
ClassMethod PadStr(pStr As %String, pLen As %Integer, pZero As %String = 0) As %String [ Private ]
{
If $Length(pStr)>pLen Quit pStr
Quit $Translate($Justify(pStr, pLen), " ", pZero)
}
 
Line 1,215:
The standard <code>strconv</code> package functions <code>ParseInt</code>, <code>ParseUint</code>, <code>FormatInt</code>, <code>FormatUint</code>,
and the standard <code>math/big</code> package method <code>SetString</code>,
all accept a base argument <code>2    base    36</code>.
 
Note, there is no equivalent formatting function provided for a <code>big.Int</code>, only the standard bases are available via <code>fmt</code> integer formatting verbs
Line 1,953:
<lang M2000 Interpreter>
Module Checkit {
k$=lambda$ (m, b as integer=16) -> {
if b<2 or b>16 then error "base out of range"
if m=0 then ="0" : exit
z$="0123456789ABCDEF"
=lambda$ z$, b (m) ->{
=if$(m=0->"", lambda$(m div b)+mid$(z$, m mod b + 1, 1))
}(m)
}
k=lambda (m$, b as integer=16) -> {
if b<2 or b>16 then error "base out of range"
m$=trim$(m$)
if m$="0" then =0 : exit
z$="0123456789ABCDEF"
=lambda z$, b (m$) ->{
=if(Len(m$)=0->0, lambda(mid$(m$,2))+(instr(z$, left$(m$,1))-1)*b**(len(m$)-1))
}(m$)
}
Print k$(0)="0", k("0")=0
Print k$(65535)="FFFF", k("FFFF", 16)=65535
Print k$(0xF00F)="F00F", k("F00F", 16)=0xF00F
Print k$(0xFFFFFFFF)="FFFFFFFF", k("FFFFFFFF", 16)=0xFFFFFFFF
Print k$(100, 8)="144", k("144", 8)=100
Print k$(100, 2)="1100100", k("1100100", 2)=100
}
Checkit
Line 2,006:
<lang Maple>#converts a number to a given based represented by a string
to_base := proc(num, based)
local i;
local chart := "0123456789abcdefghijklmnopqrstuvwxyz";
local conversion := ListTools:-Reverse((convert(num,base,based)));
local str := StringTools:-StringBuffer();
for i in conversion do
str:-append(chart[i+1]);
end do;
return str;
end proc:
 
#find the location of char in chart
find_digit := proc(char)
if (StringTools:-HasAlpha(char)) then
return (StringTools:-Ord(char) - 87);
else
return (StringTools:-Ord(char) - 48);
end if;
end proc:
 
#converts a string with given base to a number
from_base := proc(str, base)
local char;
local result := 0;
for char in str do
result *= base;
result += find_digit(char);
end do;
return result;
end proc:</lang>
{{Out|Usage}}
Line 2,072:
=={{header|МК-61/52}}==
<pre>
П8 -> 1 0 П0 ПП 13 ИП7 П0 ИП8
ПП 13 С/П П7 -> П6 -> 1 П4 П5
Сx <-> ^ ПП 68 П3 - ИП7 * П2
ПП 68 ИП4 ИП6 * П4 / + ИП2 ИП1
- x#0 45 L0 27 -> ИП3 ^ ИП7 /
ПП 68 ИП7 * - ИП5 * + ИП5 ИП6
* П5 -> ИП1 x=0 47 -> В/О 1 +
П1 КИП1 -> -> ИП1 В/О
</pre>
 
Line 2,147:
Error -- Input: z, radix: 37
java.lang.NumberFormatException: Radix out of range
at java.math.BigInteger.<init>(BigInteger.java:294)
at RNonDecRadixConvert.toDecimal(RNonDecRadixConvert.nrx:77)
at RNonDecRadixConvert.main(RNonDecRadixConvert.nrx:57)
</pre>
 
Line 2,604:
 
int2str <- function(x, b) {
if(x==0) return("0")
if(x<0) return(paste0("-", base(-x,b)))
map <- c(as.character(0:9), letters)
res <- ""
while (x>0) {
res <- c(map[x %% b + 1], res)
x <- x %/% b
}
return(paste(res, collapse=""))
}
 
str2int <- function(s, b) {
map <- c(as.character(0:9), letters)
s <- strsplit(s,"")[[1]]
res <- sapply(s, function(x) which(map==x))
res <- as.vector((res-1) %*% b^((length(res)-1):0))
return(res)
}
 
Line 2,845:
<tr align=right><td> 71</td><td> 34</td><td>23</td><td>71</td></tr>
<tr align=right><td> 61</td><td> 23</td><td>2f</td><td>61</td></tr></table>
 
=={{header|Rust}}==
<lang Rust>fn format_with_radix(mut n: u32, radix: u32) -> String {
assert!(2 <= radix && radix <= 36);
 
let mut result = String::new();
 
loop {
result.push(std::char::from_digit(n % radix, radix).unwrap());
n /= radix;
if n == 0 {
break;
}
}
 
result.chars().rev().collect()
}
 
fn parse_with_radix<S: AsRef<str>>(s: S, radix: u32) -> Result<u32, S> {
assert!(2 <= radix && radix <= 36);
 
let mut result = 0;
for digit in s.as_ref().chars().map(|it| it.to_digit(radix)) {
match digit {
Some(value) => result = result * radix + value,
None => return Err(s),
}
}
 
Ok(result)
}
 
#[cfg(test)]
#[test]
fn test() {
for value in 0..100u32 {
for radix in 2..=36 {
let s = format_with_radix(value, radix);
let v = parse_with_radix(s, radix).unwrap();
assert_eq!(value, v);
}
}
}
 
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("{}", format_with_radix(0xdeadbeef, 2));
println!("{}", format_with_radix(0xdeadbeef, 36));
println!("{}", format_with_radix(0xdeadbeef, 16));
println!("{}", parse_with_radix("DeadBeef", 16)?);
Ok(())
}</lang>
 
=={{header|Scala}}==
Anonymous user