在Scala中格式化二进制值

Jac*_*ack 31 scala string-formatting

Scala是否有内置的二进制数据格式化程序?

例如,打印输出:00000011表示Int值3.

写一个并不难 - 只是好奇它是否存在.

Lau*_*uri 61

scala> 3.toBinaryString
res0: String = 11
Run Code Online (Sandbox Code Playgroud)

Scala有一个从Int到RichInt的隐式转换,它有一个方法toBinaryString.此功能不会打印前导零.


Hos*_*Aly 20

我不知道直接的API方法,但这是一种方法:

def toBinary(i: Int, digits: Int = 8) =
    String.format("%" + digits + "s", i.toBinaryString).replace(' ', '0')
Run Code Online (Sandbox Code Playgroud)


use*_*own 10

带有前导零的数字3的8位数字:

printf ("%08d", 3.toBinaryString.toInt)
00000011
Run Code Online (Sandbox Code Playgroud)

由于Hosam Aly建议也创建一个String,这里有一个方法:

def asNdigitBinary (source: Int, digits: Int): String = {
  val l: java.lang.Long = source.toBinaryString.toLong
  String.format ("%0" + digits + "d", l) }
Run Code Online (Sandbox Code Playgroud)

在一般情况下,使用Long更合适,因为二进制值变得非常快:

scala> asNdigitBinary (1024*512-1, 32)
res23: String = 00000000000001111111111111111111
Run Code Online (Sandbox Code Playgroud)

所以记住这一点 - 一个自制的,递归的方法,逐个数字生成并最终填充它们很容易处理BigInt的任意值.

def toBinDigits (bi: BigInt): String = { 
  if (bi == 0) "0" else toBinDigits (bi /2) + (bi % 2)}

def fillBinary (bi: BigInt, len: Int) = { 
  val s = toBinDigits (bi)
  if (s.length >= len) s 
  else (List.fill (len-s.length) ("0")).mkString ("") + s
}
Run Code Online (Sandbox Code Playgroud)

如果,那会很好

def asNdigitBinary (source: Int, digits: Int): String = {
  val l = BigInt (source.toBinaryString.toLong) 
  String.format ("%0" + digits + "d", l)}
Run Code Online (Sandbox Code Playgroud)

会工作,但"%0Nd"与BigInt数字不匹配.也许应该提出Bugreport/Feature请求?但是对于Scala还是Java?


小智 6

I usually use to prepend zeroes of the wanted length -1 and then just chop the rightmost characters:

"0000000" + 3.toBinaryString takeRight 8
Run Code Online (Sandbox Code Playgroud)

This works fine for negative values as well.

  • 也可以推广到 ("0" * width) + n.toBinaryString takeRight width (2认同)