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)0x41a0110 0001( 0x61)。

因此'a' - 'A'is 0x20or 0010 0000,这是您必须在小写字母上清除以使其大写的位。

您可以从下表中看到,大写的范围从0x41through0x5a和等效的小写字母从0x61through 0x7a

在此处输入图像描述

清除位位置的方法是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) 假设您将字符 'p' 传递给您的方法toUpper()

2) 现在您的 if 语句中的条件将始终为真,因为任何字母都介于“a”和“z”之间。

3)在 if 语句中,您有以下代码

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

4)在上述声明中这部分

('a' - 'A')

将始终首先执行,因为它在括号中。在这里,您只是从“a”中减去“A”,即 97-65,它们是 ASCII 值。(A---> 65 和 a----> 97)。因此,无论您传递给toUpper()方法的字符如何,答案总是 32 。

5) 那么怎么有操作符~

~('a' - 'A')

正如我所说的 ('a' - 'A') 的答案总是 32,因此运算符 ~ 应用于数字 32 即

~32

预测算子~的输出,公式如下图

~(number)
= -(number) - 1


因为这里的数字是 32,所以上面公式的 ~32 的输出是

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

所以输出

~('a' - 'A')

总是-33

5)现在你有

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

IE

(c & -33)

这里 c 有用户传递的字母表,在我们的例子中是 'p'

IE

p & -33

由于 'p' 的 ASCII 值是 112,即

112 & -33

IE

1110000 & 1011111

分别是二进制112和-33的对应值

所以在应用运算符 & 我们得到

1010000

6) 现在将 1010000 转换为十进制,我们得到 80,这是大写字母“P”的 ASCII 值。

7)所以一般来说我们可以说将要执行的操作是

(ASCII value of user inputted alphabet) & -33

8)还有一件事“Java适用于Unicode。但是Unicode中的第一组字符是ASCII,@paxdiablo也说过。所以我在上面的答案中提到了ASCII。

于 2013-04-24T04:49:41.353 回答
1

在 Java 中,字符只是无符号的 16 位整数。

对于 ascii,小写字符为 97-122,对应的大写字母为 65-90。所以你只需要从每个值中减去 32。

如果您查看代码(char) (c & ~('a' - 'A')),您可以从内而外地评估它开始。

'a' - 'A'给你所需偏移量的负数,32。

~(32)翻转位,所以你现在有 -33。这是一个位掩码,除了倒数第六位 1 之外的所有内容。

(c & -33)应用位掩码,将适当的位设置为 0。这实际上减去了 32。

(char)只是做一个不必要的转换回 char (编译器无论如何都会插入一个转换)。

于 2013-04-24T03:15:20.787 回答
0

字符表示为数字。请查看ascii 表以了解每个字符被映射到的数字。

上面的按位运算,基本就是把小写字母对应的数字变成了大写字母对应的数字

于 2013-04-24T03:15:19.517 回答