Convert a Long to base 36 in scala
Asked Answered
P

5

22

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.

Positronium answered 19/2, 2013 at 4:13 Comment(0)
E
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

Eventuate answered 19/2, 2013 at 4:27 Comment(4)
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!Positronium
@Positronium - 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".Ales
Do you know if there is a way to do the opposite? Read from base n to a long?Cynosure
@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.Eventuate
C
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.

Caltanissetta answered 24/3, 2013 at 19:23 Comment(3)
This is a better answer. ThnxRibald
It would be even better if it used val instead of varBattology
damn! Didn't think there's a variant of toString that would take radix as a parameter. Thanks!Lovejoy
E
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

Eventuate answered 19/2, 2013 at 4:27 Comment(4)
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!Positronium
@Positronium - 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".Ales
Do you know if there is a way to do the opposite? Read from base n to a long?Cynosure
@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.Eventuate
B
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
Barrack answered 19/4, 2015 at 7:58 Comment(0)
L
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.

Lalonde answered 19/2, 2013 at 4:43 Comment(1)
Thanks for taking the time to help me nail down the process for solving problems on my own, much obliged.Positronium
O
-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
Olaolaf answered 6/3, 2014 at 12:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.