开发者

How to write binary literals in Scala?

Scala has direct support for using hex and octal numbers:

scala> 01267 + 0100
res1: Int = 759

scala> 0x12AF + 0x100
res2: Int = 5039

but how do y开发者_JAVA技巧ou do express an integer as a binary number in Scala ?.


If performance is not an issue, you can use a String and convert it to an integer.

val x = Integer.parseInt("01010101", 2)

Binary numbers aren't supported directly in part because you can easily convert from hexadecimal to binary and vice versa. To make your code clearer, you can put the binary number in a comment.

val x = 0x55 //01010101


In 2.10 you can create a string interpolator for that, e.g. it's possible to write b"0010" to mean 2. Using macros you can get rid of associated runtime overhead and do the conversion at compile-time. Take a look at Jason Zaugg's macrocosm to see it in action:

scala> b"101010"
res4: Int = 42

scala> b"102"
<console>:11: error: exception during macro expansion: invalid binary literal
              b"102"
              ^


Using the new "implicit class" and "value class" mechanisms in 2.10, you can write something like this to add convenience methods without the overhead of object creation:

implicit class IntToBase( val digits:String ) extends AnyVal {
  def base(b:Int) = Integer.parseInt( digits, b )
  def b = base(2)
  def o = base(8)
  def x = base(16)
}

That allows you to do things like

"555".o  // 365 decimal

and no IntToBase object is ever actually created.


You would need to be careful if you're converting from an integer that "looks like" binary as @agilesteel suggests. For example 0101.b would try to convert 65 decimal to binary (initial 0 signifying octal), whereas 101.b would try to convert 101 decimal to binary. It only really makes sense to try to convert from a String, for which there is Integer.parseInt, and from a number to the binary String representation, for which there is Integer.toString(x, 2).

I can't think of too many use-cases for programmatic binary literals. That said, they've made it to Java 7 as a number with prefix 0b, so I'd be surprised if they didn't appear in Scala soon. Java seems to have done fine without them for 15 years though.


If you are planning on using it a lot you can simulate the behavior with an implicit conversion.

object Extensions {
  implicit def conversion(x: Int) = new BinaryInt(x)
  class BinaryInt(x: Int) {
    def b = {
      // Conversion code like Integer.parseInt
      // as Kim suggested
    }
  }
}

Now you can do stuff like

import Extensions._
val x = 0101.b
// or
val x = 5.b

You have to decide for yourself, which direction the conversion should go.


If you want to get a string of the binary representation of an Int you can call 4.toBinaryString. Padding is more difficult. You'll have to do something like: 4.toBinaryString.reverse.padTo(8, "0").reverse.mkString


def _0b(row: Int): Int = {
  row.toString
    .reverse
    .split("")
    .zipWithIndex
    .map(x => (x._1.toInt, x._2))
    .filter(_._1 == 1)
    .map(x => Math.pow(2,x._2).toInt)
    .sum
}

_0b(10011001) = 153

Though it is limited to 32Bit Values

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜