在Scala中将一个长整型转换为36进制

21

如何将 Long 转换为 base36?请解释你是如何得出答案的?

我查看了 Long 的 scaladocs,以了解如何将其转换为不同的进制,以及如何将 Long 转换为 BigInt。我发现 BigInt 中有一个 toString(base) 方法,因此解决方案可以涉及更改类型,但我无法弄清楚如何实现。

注:我是 Scala / Java / 类型安全语言的新手,因此可能忽略了一些微小的问题。

5个回答

42

在Scala语言中,将Long 转换为 BigInt 很简单:

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

输出结果为:

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

我之前是Java开发者,现在正在学习Scala(阅读《Scala for the Impatient.pdf》第1章)。上面的回答虽然能用,但感觉很奇怪。对于这么基本的转换,不得不跳到Java领域中似乎不太正确,特别是当BigInt已经具备所有这些功能时。在查看scaladoc和上面的答案后,出现了一些问题。

我最大的错误是使用toInt()方法,它会使myLong值截断得非常严重。当我将放弃时,最终的尝试却似乎如此简单和直观,以至于我几乎没有尝试它:myBigInt = myLong。也许有一天,Long类型会更加丰富并理解toBigInt方法... 这是我的旅程中第一个失败。


2
这是一个更好的答案。谢谢。 - Ward
1
最好使用val而不是var,这样会更好。 - Bart Swennenhuis
天啊!我没想到还有一个可以接受基数参数的“toString”变种。谢谢! - asgs

29

类 java.lang.Long 有一个静态方法 toString(long i, int radix),它可以将 Long 类型转换为另一进制的字符串表示。在这个上下文中,“基数”与“进制”意思相同。

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

Scala 在必要时会将您的 scala Long 值视为 java.lang.Long,因此在需要时可以始终在 Java API 文档中查找方法。参见:http://docs.oracle.com/javase/6/docs/api/java/lang/Long.html


2
你知道你必须去使用 Java 的 Long 类吗?我正在尝试学习 Scala,但没有 Java 经验,有时感觉不知道该到哪里寻找答案...这是我的代码:def hasher(id: Long): String = { java.lang.Long.toString(id, 36) }谢谢你,Josh! - AKnox
1
@AKnox - 很多功能来自Java而不是被复制; 如果有相关的类,总是值得检查那里的内容。此外,那似乎是一个非常糟糕的哈希函数选择,但也许你指的是一些非标准的“哈希”方式。 - Rex Kerr
你知道是否有一种方法可以做相反的事情吗?从基数n读取到long? - Chetan Bhasin
2
如果你想将一个基于radix进制的字符串转换成long类型,可以使用 @ChetanBhasin 提到的 java.lang.Long.parseLong(String s, int radix) 方法。 - Josh Marcus

8

所以你想将Long转换为BigInt。BigInt对象有一个接收Long作为参数的apply方法。这里是在REPL中的一个示例。

scala> BigInt(458982948578L).toString(36)
res11: String = 5uuqlhpe

5

要么这个方法可以在Scala的Long或其增强类RichLong上使用,要么你必须在Java的对应类中查找。后一种情况是发生的。

它可能出现在源类型或目标类型上,由于long不是Java中的一个类,因此您必须在java.lang.Long上查找。它不在String上 - 查找接受Long的方法 - 但您可以在java.lang.Long上找到它,只需查找返回String的方法即可。


感谢您抽出时间帮助我掌握解决问题的方法,非常感激。 - AKnox

-1

一般形式

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

(反之亦然)

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接