在进行字符算术时,您是否在基数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是规则吗?
答案 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