该方法可以实现任意两个整数相除, 结果提取循环节,
例如2.333…显示2.[3].
结果可以转换成任意进制(2-36进制)
import java.util.ArrayList;
import java.util.List;
public class RadixDivision {
final String code = "0123456789abcdefghijklmnopqrstuvwxyz";
int precision = 200; //最多取小数点后200位
/** 计算除法:
dvd被除数 dividend, dvs除数 divisor,
q商数 quotient, r余数 reminder;
rlist余数列表, radix结果是几进制的 */
private String div(int dvd, int dvs, int radix) {
List<Integer> rlist = new ArrayList<Integer>();
String ret = "";
int q, r, j, index;
q = dvd / dvs;
r = dvd % dvs;
rlist.add(r);
//先计算整数部分
ret = transRadix(q,10,radix);
if(r == 0) {
return ret;
}
ret += ".";
for(int i=0; i<precision; i++){
r*=radix;
q = r/dvs;
r = r % dvs;
//如果小数部分整除,则返回结果
if(r==0) {
ret += transRadix(q, 10, radix);
return ret;
}
//如果没有整除,检查余数和以前是否重复,重复部分的商数是循环节,用[]表示
j = checkLoop(rlist, r);
if(j > -1){
ret += transRadix(q, 10, radix);
index = ret.length() - rlist.size() + j;
ret = ret.substring(0, index) + "[" + ret.substring(index, ret.length()) + "]";
return ret;
}
//余数没有重复则再朝下算一位
ret += transRadix(q, 10, radix);
rlist.add(r);
}
return ret;
}
/** 检查当前的余数是否和以前重复. 如果重复, 则重复部分的商数是循环节 */
private int checkLoop(List<Integer> rlist, int r) {
for(int i=0; i<rlist.size(); i++){
if(rlist.get(i) == r){
return i;
}
}
return -1;
}
/** 把数字num从from进制转换成to进制 */
String transRadix(int num, int from, int to) {
int number = Integer.valueOf(num + "", from);
StringBuilder sb = new StringBuilder();
while (number != 0) {
sb.append(code.substring(number % to, number % to + 1));
number = number / to;
}
if(sb.length()==0){
sb.append("0");
}
return sb.reverse().toString();
}
public static void main(String[] args) {
RadixDivision main = new RadixDivision();
System.out.println(main.div(2, 3, 6));
System.out.println(main.div(4, 3, 2));
System.out.println(main.div(10, 7, 10));
System.out.println(main.div(1200, 23, 36));
}
}
计算6进制的2/3, 2进制的4/3, 10进制的10/7, 36进制的1200/23
执行结果:
0.4
1.[01]
1.[428571]
1g.[69e34p1kcis]