是否有Scala方式来获取数字的长度?

时间:2012-08-12 13:52:58

标签: scala numbers

我想知道,如果有一个Scala内置方法来获取整数的十进制表示的长度?

示例:45的长度为2; 10321的长度为5

可以使用10321.toString.length得到长度,但由于创建String对象时的开销,这有点气味。有更好的方法还是内置的方法?

更新:

  • 有更好的'我的意思是更快的解决方案
  • 我只对正整数感兴趣

8 个答案:

答案 0 :(得分:5)

如果您想要速度,那么类似下面的内容非常好,假设随机分布:

def lengthBase10(x: Int) =
  if      (x >= 1000000000) 10
  else if (x >= 100000000)   9
  else if (x >= 10000000)    8
  else if (x >= 1000000)     7
  else if (x >= 100000)      6
  else if (x >= 10000)       5
  else if (x >= 1000)        4
  else if (x >= 100)         3
  else if (x >= 10)          2
  else                       1

如果您想要的只是最低限度,那么计算双精度的对数效率不高。

传统的递归方式是:

def len(x: Int, i: Int = 1): Int = 
  if (x < 10) i 
  else len(x / 10, i + 1)

比在0到10e8范围内的整数记录更快。

上面的

lengthBase10比其他所有内容快4倍。

答案 1 :(得分:4)

这绝对是个人偏好,但我认为对数方法在没有分支的情况下看起来更好。仅对于正值,当​​然可以省略abs

def digits(x: Int) = {
    import math._
    ceil(log(abs(x)+1)/log(10)).toInt
}

答案 2 :(得分:3)

toString然后获取int的length将不适用于负整数。此代码不仅适用于正数而且适用于负数。

def digits(n:Int) = if (n==0) 1 else math.log10(math.abs(n)).toInt + 1;

答案 3 :(得分:2)

记录到基地10,发言并添加1.

答案 4 :(得分:1)

这样的事情应该可以胜任:

def numericLength(n: Int): Int = BigDecimal(n).precision

答案 5 :(得分:0)

最简单的方法是:

def numberLength(i : Int): Int = i.toString.length

您可以添加一个防护条件,因为负Int的长度为abs + 1.

答案 6 :(得分:0)

另一种可能是:

private lazy val lengthList = (1 until 19).map(i => i -> math.pow(10, i).toLong)

def numberSize(x: Long): Int =
  if (x >= 0) positiveNumberSize(x)
  else positiveNumberSize(-x) + 1

private def positiveNumberSize(x: Long): Int =
  lengthList
    .collectFirst {
      case (l, p) if x < p => l
    }
    .getOrElse(19)

答案 7 :(得分:-1)

解决办法如下:

number.toString.toCharArray.size     

输入 - 输出

45   -   2
100  -   3