为什么这些按位运算会产生大写字母?

时间:2013-04-24 03:07:04

标签: java bitwise-operators

我有以下代码:

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

    return c;
}

为什么这可以正确地提出大写字母?按位操作是我最感兴趣的。我或多或少地理解数学,我理解它确实有效但不是为什么它工作的根本原因。

4 个答案:

答案 0 :(得分:3)

它的工作原理是,在ASCII(与Unicode的下半部分相同)中,A的位模式为0100 00010x41),而a0110 00010x61)。

因此'a' - 'A'0x200010 0000,这是您需要清除小写字母以使其成为大写字母的位置。

您可以从下表中看到,大写字母范围从0x410x5a以及从0x610x7a的等效小写字母:

enter image description here

清除位位置的方法是and它与该位置的逻辑否定。

因此(使用8位),~0x200xdf1101 1111),字母c的操作如下:

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

有关按位运算符的更详细介绍,请参阅here


当然,值得一提的是你可以更容易地使用:

c = Character.toUpperCase (c);

没有必须编写自己的函数。有关详细信息,请参阅here。而且,如果您真的想将其限制为ASCII小写字母,您仍然可以将其包装在if语句中,但我建议如果您希望您的应用程序在非ASCII中使用,那不是一个好主意世界。

答案 1 :(得分:1)

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

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

如果你看一下代码(char) (c & ~('a' - 'A')),你可以先从内部进行评估。

'a' - 'A'为您提供所需偏移的负数,32。

~(32)翻转位,所以你现在有-33。除了第六位到最后一位之外,这是一个掩码。

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

(char)只是对char进行不必要的强制转换(编译器无论如何都会插入一个强制转换)。

答案 2 :(得分:1)

让我们举个例子来理解你的代码。

1)假设您将字符“p”传递给方法 toUpper()

2)现在if语句中的条件将始终为true,因为任何字母都在'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

要预测运算符〜的输出,公式如下所示

〜(数字)
= - (数字) - 1

由于这里的数字是32,因此从上面的公式输出~32是< / p>

- (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

是二进制

中112和-33的对应值

因此在应用运算符&amp;我们得到

1010000

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

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

(ASCII value of user inputted alphabet) & -33

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

答案 3 :(得分:0)

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

上面的按位操作基本上将对应于小写字母的数字改为大写字母

的数字