2012-02-25 16 views
28

¿Scala tiene un formateador incorporado para datos binarios?Formateo de valores binarios en Scala

Por ejemplo, para imprimir: 00000011 para el valor Int 3.

escribir uno no va a ser difícil - sólo por curiosidad, si es que existe.

Respuesta

56
scala> 3.toBinaryString 
res0: String = 11 

Scala tiene una conversión implícita de int a RichInt que tiene un método toBinaryString. Sin embargo, esta función no imprime los ceros a la izquierda.

20

No sé de un método de API directa de hacerlo, pero aquí es una forma de hacerlo:

def toBinary(i: Int, digits: Int = 8) = 
    String.format("%" + digits + "s", i.toBinaryString).replace(' ', '0') 
+1

+1 para agregar ceros ;-) – Jack

+0

@JacobusR Gracias. De hecho, creo que eso es lo que preguntaste, ya que fuiste muy claro en tu pregunta, pidiendo "formateador * integrado *", ¡no convertidor! –

2

Esta es una manera más (edad Java):

val x = 5 
val str = Integer.toString(x,2) 

Al igual que la respuesta Lauri, que no imprime ceros a la izquierda.

+0

Sigo olvidando que no hay nada de malo en usar Java en Scala – Jack

0

Usted puede hacer algo como esto:

scala> val x = 3 
x: Int = 3 

scala> Integer.toString(x, 2) 
res4: java.lang.String = 11 

Al igual que con otras sugerencias, esto no tienen ceros a la izquierda ...

9

8 dígitos para el número 3 con ceros a la izquierda:

printf ("%08d", 3.toBinaryString.toInt) 
00000011 

Dado que Hosam Aly también sugiere crear una cadena, este es un método para hacerlo:

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

En el caso general, el uso de una larga es más apropiado, ya que los valores binarios hacer larga muy rápido:

scala> asNdigitBinary (1024*512-1, 32) 
res23: String = 00000000000001111111111111111111 

así que tenlo en cuenta - un enfoque hecho a sí mismo, recursiva que genera dígito a dígito y las llena hasta el final se haría fácilmente para manejar valores arbitrarios de 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 
} 

Sería bueno, si

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

quiere trabajar, pero "% 0ND" no coincide para los dígitos BigInt. ¿Tal vez se debe hacer una solicitud de informe/función de error? ¿Pero para Scala o Java?

+0

Esta es una buena respuesta, excepto que imprime el resultado en lugar de almacenarlo en una variable utilizable. Puede intentar esto en su lugar: 'String.format ("% 08d ", 3.toBinaryString.toInt.asInstanceOf [Object])' –

+0

@HosamAly: 'Por ejemplo para imprimir: 00000011 para el valor Int 3.' –

+0

Bueno captura. :) Sin embargo, sería valioso agregar la versión genérica a su respuesta. Lo habría agregado al mío, pero creo que es tu idea. –

1

Esto imprimirá los ceros a la izquierda:

def int2bin(i: Int, numPos: Int): String = { 
    def nextPow2(i: Int, acc: Int): Int = if (i < acc) acc else nextPow2(i, 2 * acc) 
    (nextPow2(i, math.pow(2,numPos).toInt)+i).toBinaryString.substring(1) 
    } 
0

que suelen utilizar para anteponer los ceros de la longitud deseada -1 y luego simplemente picar los caracteres más a la derecha:

"0000000" + 3.toBinaryString takeRight 8 

Esto funciona bien para el negativo valores también.