Convert an integer to base36
Asked Answered
A

3

8

strtoi(x,base=36) will convert a base36-encoded string to an integer:

strtoi("zzzz",base=36)
[1] 1679615

Is there a function that inverts this operation, i.e., given a positive integer yields the base36 equivalent? Essentially, I'm looking for an itostr() function such that

itostr(1679615,base=36)
[1] "zzzz"

(I don't need any base other than 36, but a base argument would be nice to have.)

Archi answered 16/3, 2016 at 12:57 Comment(2)
also github.com/statsmaths/baseNThigmotaxis
Not a duplicate, but a similar question is discussed here.Jerkwater
G
7

I believe if you install the package BBmisc, it has the itostr function is available.

library(BBmisc)
itostr(1679615,base=36)
[1] "zzzz"
Garald answered 16/3, 2016 at 13:47 Comment(0)
B
5

I don't know of any implementations, but the algorithm isn't that difficult. Here's one that works on 32-bit signed integers.

intToBase36 <- function(int) {
  stopifnot(is.integer(int) || int < 0)

  base36 <- c(as.character(0:9),LETTERS)
  result <- character(6)
  i <- 1L
  while (int > 0) {
    result[i] <- base36[int %% 36L + 1L]
    i <- i + 1L
    int <- int %/% 36L
  }
  return(paste(result, sep="", collapse=""))
}

You could use the bit64 and Rmpfr packages if you need to support larger integers.

Blunge answered 16/3, 2016 at 13:39 Comment(1)
Nice. I was a bit taken aback that it broke on intToBase36(1679615), but then again, of course is.integer(1679615) is FALSE, and a little coercing using intToBase36(1679615L) does the trick.Archi
H
4

A quick Rcpp hack of this will get you it as well:

library(inline)

cxxfunction(signature(x="numeric"), body='
unsigned int val = as<unsigned int>(x);
static char const base36[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
std::string result;
result.reserve(14);
do {
  result = base36[val % 36] + result;
} while (val /= 36);
return wrap(result);
', plugin="Rcpp") -> base36enc

base36enc(36)
## [1] "10"

base36enc(72)
## [1] "20"

base36enc(73)
## [1] "21"

It definitely needs a bit more code for production use, though.

The BBmisc package referenced in another answer is also C-backed so it's probably a good, performant choice.

Hesta answered 16/3, 2016 at 13:57 Comment(2)
#ty Joshua. I have no idea how that happened (and I should have caught it)Hesta
This looks interesting, but to be honest, it's a bit intimidating for me as a non-Rcpp-user. (I assume the canonical rejoinder is that I should become an Rcpp user. I plead lack of time.) Plus, I get cryptical errors that may be connected to my German default locale: "include/Rcpp/Date.h:103: error: field ‘m_tm’ has incomplete type".Archi

© 2022 - 2024 — McMap. All rights reserved.