正过程:
private static String toRadixNumber(int raw, int rawRadix) {
// 4 10
if (rawRadix < 2){
throw new IllegalArgumentException("进制非法!");
}
if (rawRadix > 16){
throw new IllegalArgumentException("只能支持到十六进制,谢谢!");
}
StringBuilder s = new StringBuilder();
char[] matchers = {'a', 'b', 'c', 'd', 'e', 'f'};
if (raw / rawRadix == 0) {
matchRadix(s, matchers, raw, rawRadix);
return s.toString();
}
while (raw / rawRadix != 0) {
s.insert(0, raw % rawRadix <= 9 ? "" + raw % rawRadix : "" +matchers[raw % rawRadix % 10]);
raw /= rawRadix;
matchRadix(s, matchers, raw, rawRadix);
}
return s.toString();
}
这里为8进制和16进制的匹配过程
private static void matchRadix(StringBuilder s, char[] matchers, int raw, int rawRadix){
if (raw / rawRadix == 0) {
if (rawRadix == 8) {
s.insert(0, "0" + raw);
return;
}
if (raw > 9){
if (rawRadix == 16){
s.insert(0, "0x" + matchers[raw % 10]);
return;
}
s.insert(0, matchers[raw % 10]);
return;
}
if (rawRadix == 16){
s.insert(0, "0x" + raw);
return;
}
s.insert(0, "" + raw);
}
}
逆过程:中间又调用正过程的转换,如果输入的数值是负数,那么在转成二进制时会在头部增加符号位,没有输入的二进制正负判断。
private static String fromRadixToSpecificRadix(String raw, int rawRadix, int toRadix){
if (rawRadix < 2 || toRadix < 2){
throw new IllegalArgumentException("进制非法!");
}
if (rawRadix == toRadix)
{
return raw;
}
if (raw.startsWith("0x")){
if (rawRadix != 16){
throw new IllegalArgumentException("原始进制数据给定错误!");
}
}
if (raw.startsWith("0") && rawRadix != 16){
if (rawRadix != 8){
throw new IllegalArgumentException("原始进制数据给定错误!");
}
}
int i = 0;
boolean isNegative = false;
if (rawRadix == 16){
if (!raw.startsWith("0x") || raw.length() <= 2){
throw new IllegalArgumentException("参数错误!原始进制数据格式错误或给定原始数据类型非16进制数据类型!");
}
if (raw.contains("-")){
i = 3;
isNegative = true;
}else {
i = 2;
}
}
if (rawRadix == 8){
if (!raw.startsWith("0") || raw.length() <= 1){
throw new IllegalArgumentException("参数错误!原始进制数据格式错误!给定原始数据类型非8进制数据类型!");
}
if (raw.contains("-")){
i = 2;
isNegative = true;
}else {
i = 1;
}
}
if (raw.contains("-"))
{
i = 1;
isNegative = true;
}
Map<String, Integer> symbolMap = new HashMap<>(6);
symbolMap.put("a", 10);
symbolMap.put("b", 11);
symbolMap.put("c", 12);
symbolMap.put("d", 13);
symbolMap.put("e", 14);
symbolMap.put("f", 15);
// 1、还原为十进制
// 2、转为指定进制
long valueTenRadix = 0;
boolean hasChangeValue = false;
for (; i < raw.length(); i++){
try {
valueTenRadix = valueTenRadix * rawRadix + Integer.parseInt(raw.substring(i, i+1));
hasChangeValue = true;
}catch (Exception e){
int c = 0, sum = 0;
for (Map.Entry<String, Integer> set : symbolMap.entrySet()){
c++;
if (set.getKey().equals(raw.substring(i, i+1)) || set.getKey().equals(raw.substring(i, i+1).toLowerCase())){
if ((rawRadix % 10) >= c){
valueTenRadix = valueTenRadix * rawRadix + set.getValue();
hasChangeValue = true;
break;
}
}else {
sum++;
}
}
if (sum == symbolMap.size() || c > rawRadix % 10){
throw new IllegalArgumentException("给定原始进制数据有误!");
}
}
if (valueTenRadix > Integer.MAX_VALUE){
throw new IllegalArgumentException("参数过大,数值已经溢出,无法完成转换!");
}
}
if (hasChangeValue){
if (toRadix == 2){
if (isNegative){
return "1" + toRadixNumber((int)valueTenRadix, toRadix);
}
}
return toRadixNumber(isNegative ? (int)-valueTenRadix : (int)valueTenRadix, toRadix);
}else {
return raw;
}
}