21

How can I convert a Long to base36 ? Along with your answer can explain how you came to the answer?

I've checked the scaladocs for Long for converting to a different base, and on converting a Long to a BigInt. I saw that BigInt does have toString( base ) so a solution could involve changing the type, but I couldn't figure out how.

Note: I'm new to scala / java / type-safe languages so I could be overlooking something trivial.

AKnox
  • 2,455
  • 3
  • 19
  • 19

5 Answers5

42

Staying within Scala language, converting Long to a BigInt turns out to be simple:

var myLong : Long = Long.MaxValue
var myBigInt : BigInt = myLong
myBigInt.toString(36)

output being:

myLong: Long = 9223372036854775807
myBigInt: scala.math.BigInt = 9223372036854775807
res199: String = 1y2p0ij32e8e7

They way I came to topic was as a Java developer and Scala beginner (reading chapter 1 of "Scala for the Impatient.pdf"). The answers above worked but seemed strange. Having to jump into Java land for such a basic conversion seemed less correct somehow, especially when BigInt had all the stuff. After reviewing scaladoc and the answers above, a few fails followed.

My biggest fail was using toInt() which truncates myLong horridly. About to give up, the final attempt seemed so simple and intuitive that I almost didn't try it: myBigInt = myLong. Perhaps one day Long will be richer and understand toBigInt... this was my first fail in the journey.

charo
  • 715
  • 1
  • 7
  • 14
29

The class java.lang.Long has a static method toString(long i, int radix) which will convert a Long into a string representation of another base. "Radix" means the same thing as "base" in this context.

val myLong = 25000L
val longInBase36:String = java.lang.Long.toString(myLong, 36)

Scala will treat your scala Long value as a java.lang.Long when necessary, so you can always look for methods in the Java API documentation when necessary. See: http://docs.oracle.com/javase/6/docs/api/java/lang/Long.html

Josh Marcus
  • 1,749
  • 18
  • 30
  • 2
    So did you just know that you had to go to java's Long ? I'm trying to get into scala with no java experience and I feel like I don't know where to find answers sometimes... here is what I ended up with: `def hasher(id: Long): String = { java.lang.Long.toString(id, 36) }` Thank you Josh! – AKnox Feb 19 '13 at 04:41
  • 1
    @AKnox - A lot of functionality is from Java rather than being replicated; it always pays to check the relevant class there also (if there is one). Also, that seems like a singularly poor choice for a hashing function, but maybe you mean something nonstandard by "hash". – Rex Kerr Feb 19 '13 at 15:51
  • Do you know if there is a way to do the opposite? Read from base n to a long? – Chetan Bhasin Mar 23 '16 at 17:49
  • 2
    @ChetanBhasin java.lang.Long.parseLong(String s, int radix) should do the trick, if you're looking to convert a string in a base to a long. – Josh Marcus Jun 06 '16 at 20:56
8

So you want to convert Long to BigInt. BigInt object has an apply method that takes Long as a parameter. Here is an example in the REPL.

scala> BigInt(458982948578L).toString(36)
res11: String = 5uuqlhpe
climbing_bum
  • 83
  • 1
  • 2
5

Well, either the method is available on Scala's Long or its enhancement class, RichLong, or you must search for it on the Java counterpart. The latter happens to be the case.

It could be either on the source type or the destination type, and since long is not a class in Java, you'd have to look for it on java.lang.Long. It's not on String -- look for methods taking Long --, but you can find it on java.lang.Long, just looking for methods returning String on it.

Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681
  • Thanks for taking the time to help me nail down the process for solving problems on my own, much obliged. – AKnox Feb 19 '13 at 05:21
-1

General form

def nextInt(d: Double): Int = if (math.floor(d) == d) d.toInt + 1 else math.ceil(d).toInt

def digitsL(base: Int, n: Long, padTo: Int = 0): List[Int] =
  List.fill(List(padTo, nextInt(math.log(n) / math.log(base))).max - 1)()
  .foldLeft((List((n % base).toInt), base)) {
    case ((cum, div), _) => (((n / div) % base).toInt +: cum, div * base)
  }._1

(And the reverse)

def digitsToLong(base: Int, digits: List[Int]): Long = digits.foldRight((0L, 1)){
  case (cur, (cum, pow)) => (cum + cur.toLong * pow, pow * base)
}._1
samthebest
  • 30,803
  • 25
  • 102
  • 142