2014-01-19 2 views
14

コーポレートタワーのモダンな世界に(ここでは)移動しているので、私はScalaにいくつかのCコードを変換しています。Scalaの符号なしの変数

Cコードの中には、かなりの数のビットレベル(シフト)演算を実行する符号なし変数を使用するものがあります。

私はScala(およびJava)と実際にはJVMがunsigned types alienを見つけると考えているので、これらをScalaに変換する方法については完全に停止しています。

アドバイスありがとうございます。

+0

Cの符号なし変数の*タイプ*は何ですか? (例えば 'char'、' int'' long'など) –

+0

こんにちは、すべての操作は、型が定義されていないので、K&Rスタイルを想定しています。 –

+1

下記の答えは、特にスカラの場合は良いですが、ちょうどFYIのように、 'long l = i&0x00000000ffffffffL; 'を使って符号付きlong(64bit)にアップコンバートすることができます。' i'はJavaのunsigned intです。または、これらが外部ソースから来ていない場合は...単に 'long'を使用してください –

答えて

18

Cの署名されていない演算とJVMの間の唯一の違いは、右シフト演算子があります。符号なし演算の場合は論理シフト(符号拡張を望んでいないので)を使用しますが、符号付き数学ではの算術シフト(符号を保持します)を行います。これはTwo's complement arithmeticの美しさの1つです。

これに基づいて、>>>演算子のJava/Scala >>演算子を変更するだけで、ビットごとに同じ答えが得られます。しかし、何をしているのかによっては、結果を使って何かをしようとすると問題が発生する可能性があります。それを符号なし整数として出力したい場合に使用します。

Scalaで「符号なし」longを使用して数学を行い、結果を最後に出力したいとします。通常のlongを使用するだけで、>>の代わりに>>>論理シフト)演算子を使用し、符号なしの値を表すことができる最後に変換します。 @のrightfoldの答えで提案されているようにあなたは、ライブラリを使用することができ、またはあなただけのこのような単純な何かを行うことができます:

val x = Long.MaxValue // declare my "unsigned" long 
// do some math with it ... 
val y = x + 10 

// Convert it to the equivalent Scala BigInt 
def asUnsigned(unsignedLong: Long) = 
    (BigInt(unsignedLong >>> 1) << 1) + (unsignedLong & 1) 

x 
// Long = 9223372036854775807 
asUnsigned(y) 
// res1: scala.math.BigInt = 9223372036854775817 

あなただけInt Sを使用している場合は、あなたもでBigIntに変換する必要はありません。 Longが答えを保持することができます。 @BrianRoachが上の彼のコメントで提案したメソッドを使用して、Intの "符号なし"値をLongに変換するには、上位バイトをマスクしてください。しかし、絶対にする必要があるまで、変換を行わないでください。 64ビットプロセッサで64ビットJVMを使用する場合でも、Int(32ビット)よりもLong(64ビット)の方が、整数の乗算と除算の演算が遅くなります。 (詳細については、この質問を参照してください:Are 64 bit integers less efficient than 32 bit integers in the JVM?)。

7

残念ながら、JVMは符号なしデータタイプ(char、感謝Erwin以外)をサポートしていませんが、希望があります! Scalaには、十分に進化した型システムがあり、これによって、符号なしの型のように動作する独自の型を作成することができます。

すでにa libraryがあります。ライブラリはオペレータに負担をかけ、変換を提供します。

+0

多くのおかげです。私はこれを見ます。 –

+7

JVMには、符号なし16ビットのデータ型 'char'が1つあります。 'char ch = 65535; System.out。println((int)ch); 'prints' 65535' –

+0

@ErwinBolwidtあなたは正しいです。しかし、あなたがこのコメントをする1時間前に書かれた質問にコメントを読んだら、OPは32ビットのintについて話しています。 –