2011-11-20 10 views
11

こんにちは、私はこの出くわしたとき、私は(java.lang.Character)Javaのソースコードの一部を拾い読みしてすべて:char_x <(char_y + 1)== char_x <= char_y?

public static boolean isHighSurrogate(char ch) { 
    return ch >= MIN_HIGH_SURROGATE && ch < (MAX_HIGH_SURROGATE + 1); 
} 

public static boolean isLowSurrogate(char ch) { 
    return ch >= MIN_LOW_SURROGATE && ch < (MAX_LOW_SURROGATE + 1); 
} 

私は作家が上限に1を追加しなかった理由不思議とあまりよりも比較をしていました、単により小さいか等しい比較を行う代わりに?

読みやすくするために役立つかどうかは分かりますが、この場合はそうではないようです。

私は上記のコードと、この違いだと思いまして:

public static boolean isHighSurrogate(char ch) { 
    return ch >= MIN_HIGH_SURROGATE && ch <= MAX_HIGH_SURROGATE; 
} 

public static boolean isLowSurrogate(char ch) { 
    return ch >= MIN_LOW_SURROGATE && ch <= MAX_LOW_SURROGATE; 
} 
+0

これは推測であり、答えではありません。おそらく、ループのための慣用的な書き方と一貫していると思います。 'for(i = LOWER_BOUND;私は

+0

多分、chはMAX_ [HIGH | LOW] _SURROGATEと等しくなるかもしれないことを強調することを意図していました。 "<="は "<"として誤読されやすくなり、おそらくコンパイラはそれを同じバイトコードに最適化します。 –

+2

まあ、ある意味では、 'MAX_HIGH_SURROGATE'はcharであり、' 1'はintです。charからそこに行くintへの何らかの変換が必要な場合があります。 – BoltClock

答えて

2

おそらく著者は、すべてが半開きの範囲にすることがDijkstra's adviceと一致するようにしようとしている - 開始点は、包括的ですエンドポイントは排他的です。

あり、ここでない意味的な違いはないが、バイトコードの微妙な違い:(ch + 1)は、第二は、2つのcharcharとの比較を行いながら、第1のコードスニペットをintintと比較することによってcharcharと比較し、続いてないintあります。これは意味の違いにはなりません。暗黙のキャストはより広範な型になります。したがって、いずれかのコードスニペットでオーバーフローするリスクはありません。私は1つを好む任意の特定の性能の理由が表示されないよう

JITによって行わ最適化の種類の範囲内である付加を最適化し、2バイトの符号なしint比較に戻すintintとの比較を変換他のものよりも。

私は途中でchchは外の値の範囲内でテストされている読者にはそれが明らかになり、そのよう

MIN_LOW_SURROGATE <= ch && ch <= MAX_LOW_SURROGATE 

としてこの種のものを書くことが多いです。

+0

私は彼が両方の面で同じ比較を使用した方が意味があると思っていたでしょう: 'ch> =(MIN_HIGH_SURROGATE + 0)&& ch <(MAX_HIGH_SURROGATE + 1)' – Pacerier

+0

@Pacerier、同じこと。私はアンダーフロー/オーバーフローを引き起こし、オフ・バイ・ワンのエラーが目立ち、それに固執するものを選択します。 –

0

2つの異なる実装のうちの1つの利点が実際にはないので、コーディングの2つの方法の間にはまったく違いはなく、好きなだけの好みの問題だと思います。

私はなぜ作家が1つを上限に付け加えて、単純により小さいか等しい比較をするのではなく、より少ないものを比較したのだろうと思いましたか?

つまり、なぜ2番目の選択肢が好きですか?ここで何かが恋しい?

+0

私は、第二の選択肢があなたにももっと読みやすい(もっと理にかなっている)わけではないのですか? – Pacerier

+0

いいえ、私はMAXとMINの間に少なくとも1の差があることを期待しているので実際にはそうではありません。+ 1はこれを私のために持ち出します。 – philomatic

-1

著者はC++またはアセンブラの人間でした。

> =>よりも速く、実行するのが速い< = <より速くなります。実際には、< bを書くとコンパイラは< = b + 1となるため、使用可能なアセンブリ命令は< =となるため、加算と比較が行われます。その和を手作業でコードに書き込むと、C++コンパイラはコンパイル時に実際の結果の値でMIN_HIGH_SURROGATE + 1を変更します。だからあなたは指示とサイクルを得る。

しかし、この奇妙な推論は、C++やCやASMなどのコンパイル済みコードに対してのみ適用されます。

EDIT

上記の等価演算子のそれぞれの命令は(私が間違っていた)がありますが(必要であれば)、彼らはすべての減算とに煮詰めるマイクロコードで追加。次に、プロセッサは結果の符号ビットをチェックします。したがって、上記のコードの定式化はさらに高速になります。

1を加算するときにオーバーフローがないことを確認するために、マイクロプロセッサは最初に減算して加算します。

+0

その論理によって、 'b'がMAX_VALUEならば、' a Pacerier

+0

あなたはそれが起こらないことを確認する必要があります。それはプログラマーの仕事です。 – Sam

+0

x86では、少なくとも、<=と '<'の命令があります。 Javaバイトコードでも同じです。どちらも他のものより速くはならない。したがって、コンパイラが一方を他方に変換するのは疑わしいです。 –

2

ワイルド推測

サロゲート文字、基本 多言語面を超えて文字を表現するために、UTF-16でペアで を使用しているUnicodeのコードポイントの範囲のいずれか。

私の見解では、彼は8ビットのものを無視したいと考えました。つまり、最大値が0xFFだった場合です。 0xFF + 1はオーバーフローし、0x00に戻ります。比較を常に偽にする。

コードが8ビットの文字でコンパイルされている場合。 UTF-16の範囲外では常にfalseを返しますが、8ビットを超える文字をコンパイルすると0xFF + 1は0x100になりますが、それでも動作します。

これはあなたのためにいくつかの喜びをもたらします。

+0

'char'は常にjavaの符号なし16ビット整数です。最大値は0xDBFFで、最小値は0xD800です。 –

関連する問題