//基本算法:
以简单的浮点数为例:整数和小数部分分别转换
整数部分:除以R,取余,商为0为止。反写(从下往上写)
小数部分:乘以R,取整,直到小数部分为0或者取到足够精度为止,正写(从上往下写)
通过观察可以发现:这两部分的处理用递归是比较好实现的。因为出现了多次调用自己的方法,同时递归结束的条件也已经给出。
//以下是简单代码的展示:
/**
*将十进制的数转换成R进制的数(2<=R<=16)
思路:整数部分和小数部分分开转换
整数部分:除以R取余,商为0为止,反写(从下往上写)
小数部分:乘以R取整,小数部分为0或者取到足够精度为止,正写(从上往下写)
*/
import java.util.Scanner;
public class TryD2R
{
static String base = "0123456789ABCDEF";
static int count = 10; //小数转换递归时的次数不能超过10次,超过则停止。
.
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
System.out.println("------------------十进制的数转换成R进制的数命令行计算界面------------------");
System.out.print("请输入十进制的数:");
String msg = sc.next();
System.out.print("请输入带转换的进制数R: ");
int r = sc.nextInt();
System.out.print("十进制的数" + msg + "转换为" + r + "进制的数为:");
//我们用字符串接受的数据,在本次案例中涉及到小数部分和整数部分。
//因此我们可以使用将字符串转换成浮点数来进行处理。
double t = Double.parseDouble(msg); //"123.4"---->123.4
//获取整数部分
int x = (int)t;
//获取小数部分
double y = t -x;
//整数部分转换
f(x,r);
System.out.print("."); //输出小数点
//小数部分转换
g(y,r);
}
//整数部分转换:除以R取余,商为0为止,反写(从下往上写)
public static void f(int x, int r)
{
if(x == 0)
{
return;//递归结束的条件
}
else
{
f(x/r,r);
System.out.print(base.charAt(x % r)); //如果是十六进制,x%r等于11--->B
}
}
//小数部分转换:乘以R取整,小数部分为0,或者取到足够精度为止,正写。(从上往下写)
public static void g(double y, int r)
{
count--;
if(count <= 0)
{
return;//递归结束(已经取到足够精度了)
}
double m = y * r;
System.out.print((int)m);
double n = m - (int)m;
if(n <= 1e-20)//判断小数部分是否为0,浮点数不能直接和0.0比较,必须小于等于一个很小的数即可
{
return;
}
else
{
g(n,r);
}
}
}
可能还有一些情况没有考虑(如输入数据的校验),对转换后结果数据的保留等等。只是上传了一个简单参考的代码,供感兴趣的朋友参考和学习。
经过自己的测试,代码有两处需要调整一下。
第一处:如果输入的数据不带小数点(不是浮点数),那么小数点部分可以不需要转换,如果不加一个if判断语句,程序运行时会多出一个0。
修改后的代码和测试的结果截图:
我们反过来进行验算:29A = 2 * 16 * 16 + 9 * 16 + 10 = 666,计算结果正确。
第二处:
我们整数部分取余数时是返回base.charAt(x % r)的那个字符。
小数部分也类似,应该是返回base.charAt((int)m); //因为小数部分也可能会出现ABC这样的情况。
测试结果截图:
我们利用在线的进制转换器,进行了验证。在数据输入合法的情况,结果正确。
此软件暂时实现了我们的需求,可能还存在一些问题,有待取改进和完善。对于之前写得代码进行了改进和完善。