字符算术---基数8与基数10

时间:2014-02-04 03:33:39

标签: java unicode character ascii character-properties

在进行字符算术时,您是否在基数10或基数8中执行计算?我的书在基础8或65基础10中说'A'= 101但是当我将基数8中的字符值插入一个示例时,我的书给出了说明这一点我得到了一些有趣的结果。下面的代码是我的书中一个试图找到新角色的Ceaser Cipher的例子。如果我尝试转换'Y'并移动8个点以找到一个新角色,并且如果ch ='Y'且n = 8我期望得到角色'G'。

ch = (char)('A' + (Character.toUpperCase(ch) - 'A' + n) % 26); 

数学计算到65 +(89 - 65 + 8)%26 = 71(基数10)
                      101 +(131 - 101 + 8)%26 = 113(基数8)

如果我将71(基数10)转换回基数8,我将得到107,即字符'G',这是正确的字符。我的问题是为什么我不能在基数8中执行字符算术? 113是字符'K',它是错误的字符。在进行字符算术时,将所有值转换为基数10,然后将它们转换回基数8是规则吗?

2 个答案:

答案 0 :(得分:1)

认为你的问题是模数函数在两种情况下都不能使用“26” - 26(基数8)是小数点后22位;英语字母表中有32个(基数为8)字符。尝试使用

进行基数8计算
... % 32(base 8)

而不是26(基数为8)。

答案 1 :(得分:1)

计算机将值存储在内存中。其他一切都是我们愚蠢的人类大脑(和眼睛)的便利。默认情况下,在Java中,这些值的任何文本输出将在base10(十进制)中。

A在base10中为65,在base8中为101(假设我们正在讨论保留US-ASCII值的字符集)。

在Java中讨论 literals 时,默认情况下它们被解释为base10。要使用八进制文字,您需要在其前面加0

int a1 = 65;   // literals are by default base10
int a2 = 0101; // an octal literal in Java is preceded by a 0
int a3 = 'A';
System.out.println(a1 == a2 && a2 == a3); 

以上将输出true

如果你想在你的例子中,你可以通过八进制文字设置n或解析一个八进制String到一个int,你得到你期望的结果:

int n = 010; // octal literal equal to decimal 8
int a = 'A' + ('Y' - 'A' + n) % 26;
System.out.println(a);
System.out.println(Integer.toOctalString(a));

输出:

  

71
  107

您还可以解析String的八进制n

int n = Integer.valueOf("010", 8);

你真正面临的问题是尝试执行base8数学运算,但执行 base10 算术运算(并将n保留为十进制8):

int o = 101 + (131 - 101 + 8) % 26;
System.out.println(o);
System.out.println(Integer.toOctalString(o));

Java将这些文字解释为base10表示,并且肯定会导致:

  

113
  161

另一方面,你是否使用八进制文字并做同样的事情......

int o = 0101 + (0131 - 0101 + 010) % 26;
System.out.println(o);
System.out.println(Integer.toOctalString(o));

输出:

  

71
  107