Как писать двоичные литералы в Scala? - PullRequest
23 голосов
/ 26 августа 2011

Scala имеет прямую поддержку использования шестнадцатеричных и восьмеричных чисел:

scala> 01267 + 0100
res1: Int = 759

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

а как вы выражаете целое число в Scala как двоичное число?

Ответы [ 7 ]

23 голосов
/ 26 августа 2011

Если производительность не является проблемой, вы можете использовать строку и преобразовать ее в целое число.

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

Двоичные числа напрямую не поддерживаются, потому что вы можете легко преобразовать шестнадцатеричное в двоичное и наоборот. Чтобы сделать ваш код более понятным, вы можете поставить двоичное число в комментарии.

val x = 0x55 //01010101
18 голосов
/ 02 февраля 2013

В 2.10 вы можете создать для этого строковый интерполятор, например, можно написать b"0010" для обозначения 2. Используя макросы, вы можете избавиться от связанных с этим издержек времени выполнения и выполнить преобразование во время компиляции. Взгляните на макрокосм Джейсона Заугга , чтобы увидеть его в действии:

scala> b"101010"
res4: Int = 42

scala> b"102"
<console>:11: error: exception during macro expansion: invalid binary literal
              b"102"
              ^
8 голосов
/ 01 февраля 2013

Используя новые механизмы «неявный класс» и «класс значений» в 2.10, вы можете написать что-то вроде этого, чтобы добавить удобные методы без затрат на создание объекта:

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)
}

Это позволяет вам делать такие вещи, как

"555".o  // 365 decimal

и объект IntToBase вообще не создается.

6 голосов
/ 26 августа 2011

Вам нужно быть осторожным, если вы конвертируете из целого числа, которое «выглядит как» двоичное, как предполагает @agilesteel.Например, 0101.b будет пытаться преобразовать 65 десятичных в двоичную (начальная 0 означает восьмеричное), тогда как 101.b будет пытаться преобразовать 101 десятичной в двоичную.Это действительно имеет смысл пытаться преобразовать из строки, для которой есть Integer.parseInt, и из числа в двоичное представление строки, для которого есть Integer.toString(x, 2).

Я не могу думатьслишком много вариантов использования для программных двоичных литералов.Тем не менее, они добрались до Java 7 как число с префиксом 0b, поэтому я был бы удивлен, если бы они не появились в Scala в ближайшее время.Ява, кажется, прекрасно обходилась без них в течение 15 лет.

4 голосов
/ 26 августа 2011

Если вы планируете много использовать его, вы можете смоделировать поведение с неявным преобразованием.

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

Теперь вы можете делать такие вещи, как

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

Вы должны решитьдля себя, в каком направлении должно идти преобразование.

1 голос
/ 24 марта 2017

Если вы хотите получить строку двоичного представления Int, вы можете позвонить 4.toBinaryString.Заполнение сложнее.Вам нужно будет сделать что-то вроде: 4.toBinaryString.reverse.padTo(8, "0").reverse.mkString

0 голосов
/ 07 марта 2019
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

Хотя он ограничен 32-битными значениями

...