任意的R进制转换成十进制的计算小程序

本程序涉及到的算法:任意进制转换成十进制计算用按权展开。这是一个公理,无需证明,可以直接拿来使用。

采取两种解题的思路:

方案一:先不予考虑小数点的存在,当做纯整数来处理。计算出结果后再对小数点进行单独处理:把计算结果除以R的m次方(其中m为小数点后面保留的位数)。

举个简单的例子:

(12.12)3这是三进制下的一个数据:

按照方案一怎么处理呢???

1212 按权展开后 再除以3的平方即可。

以下是方案一代码的展示:

/**
*任意R进制转换成十进制的图形界面
思路:先不考虑小数点 如:(121.2)3--->1212转换成十进制后再除以3的一次方(判断小数点后面的位数)
当成纯整数处理后,从右向左算,因为R的i次方越来越大。
*/

import java.util.Scanner;

public class TryR2D
{
    public static void main(String[] args) 
    {
        String base = "0123456789ABCDEF";
        Scanner sc = new Scanner(System.in);
        System.out.println("----------------------任意的R进制转换成十进制的命令行界面计算----------------------");
        System.out.print("请输入需要转换的进制数:");
        int r = sc.nextInt();
        System.out.print("请输入" + r + "进制的数:");

        //因为接收的数据可能是浮点数,所以我们用字符串来接收数据。
        String msg = sc.next();

        System.out.print(r + "进制的数" + msg +"转换为十进制的数:");

        //在这里我们需要将字符装换成数据,如果是a或者A对应的是10,我们定义一个base。
        //找到所在字符对应的下标即可。indexOf

        int x = 0;            //保留最终的结果
        int temp = 1;        //记录R的i次方,初始值为1

        for(int i = msg.length() - 1; i >= 0; i--)
        {
            //接收字符
            char ch = msg.charAt(i);

            //出现小写字母时需要转换成大写字母
            if(ch >= 'a' && ch <= 'f')
            {
                ch = (char)(ch - ('a'-'A'));
            }

            //扫描时如果遇到小数点,我们计算时暂时先忽略
            if(ch == '.')
            {
                continue;//跳过本轮的循环,下面的代码不予执行。
            }

            //按权展开:需要x(保留最终的结果),temp(记录R的i次方)
            x = x + base.indexOf(ch) * temp;
            temp = temp * r;
        }

        //对小数点后面的位数进行处理:除以r的m次方。

        //如果没有小数点
        if(msg.indexOf('.') == -1)
        {
            System.out.print(x);
        }

        //如果有小数点
        else
        {
            int m = msg.length() - 1 - msg.indexOf('.');    //举:3.123---> 5 -1 -1 = 3  小数点后面确实保留了三位
            temp = 1;    //经过上述的循环后temp值发生了改变,下面还需要再使用,重新赋值为1
            for(int i = 0; i < m; i++)
            {
                temp = temp * r;
            }    
            //循环结束最终的temp值为R的m次方

            System.out.print(x * 1.0 / temp);
        
        }

        System.out.println();
        
    }
}
 

方案二:找出小数点所在的下标位置,使用String类中的indexOf方法即可。

这样一个数据就被拆分成了两段:前面一段和后面一段,分别按权展开进行计算。注意此时的位权前后不一样哈。

以下是方案二代码的展示:

/**
*任意R进制的数转换成十进制的数
思路:找出小数点所在的位置(下标),然后前面一段后面一段单独进行按权展开计算处理。
*/

import java.util.Scanner;

public class  TryR2D02
{
    public static void main(String[] args) 
    {
        Scanner sc = new Scanner(System.in);
        String base = "0123456789ABCDEF";        //用于位权的计算:如果是A--->10

        //输出一些提示性的语句
        System.out.println("----------------------任意的R进制转换成十进制的命令行界面计算----------------------");
        System.out.print("请输入需要转换的进制数:");
        int r = sc.nextInt();
        System.out.print("请输入" + r + "进制的数:");

        String str = sc.next();//读取r进制范围内的那个数

        System.out.print(r + "进制的数" + str +"转换为十进制的数:");

        //找出小数点所在的下标
        int index = str.indexOf('.');//index的值可能为-1

        if(index == -1)//数据中没有小数点,纯整数,依旧采用从右往左算
        {
            int x = 0;        //保留最终的数据结果
            int temp = 1;    //记录R的多少次方,初始值为1
            for(int i = str.length() - 1; i >= 0 ; i--)
            {
                //接收字符
                char ch = str.charAt(i);

                //因为我们的base库中是大写的英文字母,所以我们需要将小写转换成大写字母
                if(ch > 'a' && ch < 'f')
                {
                    ch = (char)(ch - ('a' - 'A'));
                }

                //字符转换成数据,bas库体现出来的好处:通过字符所在的下标来参与计算

                x = x + base.indexOf(ch) * temp;
                temp = temp * r;
            }

            System.out.print(x);
        }

        else//数据中如果有小数点,那么以小数点为基准,前面一段后面一段分别用按权展开进行计算。
        {
            int q1 = 0;//保留小数点前面的计算结果
            double q2 = 0;//保留小数点后面的计算结果
            int t1 = 1;                    //小数点前面的位权
            double t2 = Math.pow(r,-1);    //小数点后面的位权(浮点数)

            for(int i = index -1; i>=0; i--)//小数点前面一段的计算
            {
                //接收字符
                char zf = str.charAt(i);

                //小写字母转换成大写字母
                if(zf >= 'a' && zf <= 'f')
                {
                    zf = (char)(zf - ('a' - 'A'));
                }

                q1 = q1 + base.indexOf(zf) * t1;
                t1 = t1 * r;
            }

            for(int i = index + 1; i <= str.length() - 1; i++)//小数点后面一段的计算
            {
                //接收字符
                char nzf = str.charAt(i);

                //小写字母转换成大写字母
                if(nzf >= 'a' && nzf <= 'f')
                {
                    nzf = (char)(nzf - ('a' - 'A'));
                }

                q2 = q2 + base.indexOf(nzf) * t2;
                t2 = t2 * Math.pow(r,-1);
            }

            double sum = q1 + q2;    //两段的总和

            System.out.print(sum);
        
        }

        System.out.println();

    }
}
 

进行了多组不同数据的测试,发现两种代码的展示结果一样。

 最后进行简单总结:

两种设计的解决方案都可以,各有各的特色。方案一:先不需要考虑小数点,直接按权计算,再除。方案二:考虑小数点的位置后,进行了拆分。分为两段处理,要注意的是后面一段的数据保留为浮点数哈。同时里面可能涉及到小数点不存在的问题,需要单独处理,把逻辑思路想明白后写出来也不是很困难的。最后个人推荐方案一:总的来说方案一代码长度较短,设计比较新颖。方案二因为进行了拆分,需要多次接收字符,小写字母转换成大写字母,然后再分别计算,求和。类似的代码多次使用。方案一呢只使用了一次,最后通过除对小数点的问题进行了很好的处理。

但此程序还有不足的地方:没有进行数据的校验。比如2进制不能出现3,如果出现此类非法数据,使用该程序任然能参与计算,但是违背了我们的理论知识。感兴趣的朋友可以自行修改完善,本文只是个人的一点意见,仅大家参考和学习,感谢大家的喜欢和支持!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值