2

次のコードがあります。

static char toUpper(char c)
{
    if (c >= 'a' && c <= 'z')
        return (char) (c & ~('a' - 'A'));

    return c;
}

これで大文字が正しく認識されるのはなぜですか? ビット単位の操作は、私が最も興味を持っているものです。数学を多かれ少なかれ理解しており、それが機能することは理解していますが、なぜ機能するかについての根本的な理由は理解していません。

4

4 に答える 4

3

これが機能するのは、ASCII (Unicode の下位部分と同じ) では ( ) のビット パターンがA( 0100 0001)0x41aあるためです。0110 00010x61

したがって、またはです。これ'a' - 'A'は、小文字を大文字にするために消去する必要があるビットです。0x200010 0000

次の表から、大文字は~から、対応する小文字は0x41~までの範囲であることがわかります。0x5a0x610x7a

ここに画像の説明を入力

ビット位置をクリアする方法はand、その位置の論理否定を使用することです。

したがって (8 ビットを使用)~0x200xdf( 1101 1111) であり、文字の操作は次のcようになります。

  0110 0011     0x63 or 'c'
& 1101 1111     0xdf, or ~('a' - 'A')
  ---- ----
  0100 0011     0x43 or 'C'

ビット演算子の詳細については、こちらを参照してください。


もちろん、次のものを使用する方がはるかに簡単であることに言及する価値があります。

c = Character.toUpperCase (c);

独自の関数を作成する必要はありません。詳しくはこちらをご覧ください。また、本当に ASCII の小文字に制限したい場合は、ifステートメントでラップすることもできますが、アプリケーションを非 ASCII の世界で使用したい場合は、あまり良い考えではありません。

于 2013-04-24T03:13:59.817 に答える
2

コードを理解するために例を挙げてみましょう。

1) メソッドtoUpper()に文字「p」を渡すとします。

2) これで、アルファベットは「a」と「z」の間にあるため、if ステートメントの条件は常に真になります。

3) if ステートメント内には、次のコードがあります。

return (char) (c & ~('a' - 'A'));

4)上記のステートメントでは、この部分

('a' - 'A')

括弧内にあるため、常に最初に実行されます。ここでは、'a' から 'A' を引いているだけです。つまり、ASCII 値である 97-65 です。(A ---> 65 および a ---> 97)。したがって、 toUpper()メソッドに渡す文字に関係なく、答えは常に 32 になります。

5) 演算子~ ieはどのように存在するのか

~('a' - 'A')

('a' - 'A') の答えは常に 32 になると言ったので、演算子 ~ は 32 に適用されます。

~32

演算子 ~ の出力を予測するための式は次のとおりです。

~(数値)
= -(数値) - 1


ここでは数値が 32 であるため、上記の式からの ~32 の出力は

-(32) - 1
= -32 - 1
= -33

したがって、の出力

~('a' - 'A')

常に -33 になります

5) 今、あなたは持っています

(c & ~('a' - 'A'))

すなわち

(c & -33)

ここで c にはユーザーが渡すアルファベットがあり、この例では 'p' です。

すなわち

p & -33

「p」の ASCII 値は 112 であるため、

112 & -33

すなわち

1110000 & 1011111

これは、2 進数で 112 と -33 の対応する値です。

したがって、演算子を適用した後、 & を取得します

1010000

6) 1010000 を 10 進数に変換すると、大文字のアルファベット 'P' の ASCII 値である 80 が得られます。

7) したがって、一般的に、実行される操作は次のようになります。

(ASCII value of user inputted alphabet) & -33

8)もう1つ「JavaはUnicodeに対応しています。しかし、Unicodeの最初の文字セットはASCIIであり、@paxdiabloも言っています。したがって、上記の回答でASCIIについて言及しました。

于 2013-04-24T04:49:41.353 に答える
1

Java では、char は符号なしの 16 ビット int です。

ascii の場合、小文字は 97 ~ 122 で、対応する大文字は 65 ~ 90 です。したがって、各値から 32 を引くだけです。

コードを見ると、(char) (c & ~('a' - 'A'))裏返しに評価することから始めることができます。

'a' - 'A'必要なオフセット 32 の負の値が得られます。

~(32)ビットを反転するので、-33 になります。これは、6 番目から最後のビット 1 を除くすべてのビット マスクです。

(c & -33)ビットマスクを適用し、適切なビットを 0 に設定します。これにより、実質的に 32 が減算されます。

(char)不必要なキャストを char に戻すだけです (コンパイラはとにかくキャストを挿入します)。

于 2013-04-24T03:15:20.787 に答える
0

文字は数字で表されます。各文字が何番目にマッピングされているかを確認するには、ASCII テーブルを参照してください

上記のビット単位の操作は、基本的に小文字に対応する数値を後者の大文字に変換します

于 2013-04-24T03:15:19.517 に答える