2011-08-25 4 views
21

Scala ma bezpośrednie wsparcie dla korzystania z numerów sześciokątne i ósemkowe:Jak pisać literały binarne w Scali?

scala> 01267 + 0100 
res1: Int = 759 

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

ale skąd możemy wyrazić całkowitą jako liczbę binarną w Scala?.

+2

Zauważ, że od 2.10 użycie wiodącej cyfry 0 jako ósemkowej jest przestarzałe. – AmigoNico

Odpowiedz

19

Jeśli wydajność nie jest problemem, można użyć ciągu i przekonwertować go na liczbę całkowitą.

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

Numery binarne nie są obsługiwane bezpośrednio w części, ponieważ można łatwo przekonwertować z szesnastkowego na binarny i na odwrót. Aby uczynić twój kod bardziej przejrzystym, możesz umieścić numer binarny w komentarzu.

val x = 0x55 //01010101 
4

Jeśli planujesz używać go dużo, możesz symulować zachowanie z niejawną konwersją.

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

Teraz można zrobić rzeczy jak

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

Musisz sam zdecydować, w jakim kierunku powinny iść konwersja.

+4

Uważaj: '0101' jest liczbą ósemkową! – soc

+0

To było do 2.10. Zobacz inne komentarze. –

6

Musisz być ostrożny, jeśli konwertujesz z liczby całkowitej, która "wygląda na" tak jak sugeruje @agilesteel. Na przykład 0101.b spróbuje przekonwertować 65 dziesiętnych na binarne (początkowe 0 oznacza ósemkowo), natomiast 101.b spróbuje przekształcić 101 dziesiętnie na binarny. Naprawdę sensownie jest spróbować przekonwertować z String, dla którego istnieje Integer.parseInt, oraz z liczby na binarną reprezentację String, dla której istnieje Integer.toString(x, 2).

Nie mogę myśleć o zbyt wielu przypadkach użycia programowych literałów binarnych. Powiedział, że mają made it to Java 7 jako numer z prefiksem 0b, więc byłbym zaskoczony, gdyby nie pojawili się w Scala wkrótce. Wydaje się, że Java radzi sobie bez nich przez 15 lat.

+9

Java wykonała "dobrze" bez niepodpisanych znaków lub przyzwoitych operatorów bitowych. Mówiąc "dobrze", mam na myśli, że ludzie po prostu rezygnują z pisania rzeczy, które tego wymagają w Javie, albo cierpią na przeklinanie Javy na każdym calu. –

8

Korzystanie z nową „niejawny klasę” i mechanizmy „class wartość” W 2.10, można napisać coś takiego dodać metody wygodę bez obciążania tworzenia obiektów:

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

który pozwala robić rzeczy jak

"555".o // 365 decimal 

i żaden obiekt IntToBase nigdy nie został faktycznie utworzony.

18

W 2.10 można utworzyć interpolator ciągów dla tego, np. można napisać b"0010" w znaczeniu 2. Za pomocą makr można pozbyć się związanego z nim nakładu pracy środowiska wykonawczego i wykonać konwersję podczas kompilacji. Spójrz na Jason Zaugg na macrocosm aby zobaczyć go w akcji:

scala> b"101010" 
res4: Int = 42 

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

Jeśli chcesz uzyskać ciąg binarnej reprezentacji int można nazwać 4.toBinaryString. Obicie jest trudniejsze. Będziesz musiał zrobić coś takiego: 4.toBinaryString.reverse.padTo(8, "0").reverse.mkString