JAVA简单实现长正整数的四则运算(主要是整除)以及测试

要求:
实现十进制长正整数的四则运算(加、减、乘、整除),并进行测试;
输入两个字符串形式的运算数,计算运算结果。要求对输入合法性进行检验,对于长正整数,输入不能为’0’-‘9’以外的字符;如非法输入返回false;

实现思路

先构造出长整数数据类型BIgInteger以及相关的构造函数以及四则运算函数,对于数据类型的实现有以下两种方法:
1.可以使用Java的math包里的BigInteger数据类型直接实现,十分方便 http://blog.csdn.net/qfikh/article/details/52832196

2.不使用math包自己实现。根据自己的需要相当于仿照着math包里的BigInteger实现,直接查看源码包含其他运算很繁杂,所以在网上找到了简易的BigInteger的三则运算加减乘,然后自己就简单的补充了除法。很多都借鉴了链接的内容,里面的三则运算很详细易懂http://blog.csdn.net/piaopiao8786/article/details/7785492
其中由于输入字符串的合法性,则对于合法的字符如000012需要在构造函数中将前面的0去除,因此稍微修改了构造函数public BigInteger(String numberStr) 代码如下:

//字符串构造函数
    public BigInteger(String numberStr) {   
        if(numberStr.charAt(0) == '-'){   //判断正负
            sign = false;   
            StringBuilder sb = new StringBuilder(numberStr);   
            sb.deleteCharAt(0);   
            numberStr = new String(sb);   
        }else{   
            sign = true;   
        }   

        int count = 0;
        for(int i = 0; i<numberStr.length(); i++){//字符串有效数字前有多少个0
            if(numberStr.charAt(i) == '0'&&i != numberStr.length()-1) count++;
        }
        digits = new byte[numberStr.length()-count];   
        for(int i = 0;i < numberStr.length()-count;i++){   
            switch(numberStr.charAt(i+count)){   
            case '0': digits[i] = 0;break;   
            case '1': digits[i] = 1;break;   
            case '2': digits[i] = 2;break;   
            case '3': digits[i] = 3;break;   
            case '4': digits[i] = 4;break;   
            case '5': digits[i] = 5;break;   
            case '6': digits[i] = 6;break;   
            case '7': digits[i] = 7;break;   
            case '8': digits[i] = 8;break;   
            case '9': digits[i] = 9;break;   
            }   
        }   
    }  

除法思路:除法是在加减乘的基础上实现的,很普通的除法,由于是正整数,因此没有除以0的问题。 先判断除数与被除数位数,比较复杂的是被除数位数大于除数,我的实现是移位相减,恢复余数法。位数相等时候需要判断是否相同数值。

//接着上面链接的三则运算
//长正整数整除法(默认为正整数即不会出现除以0)
    public BigInteger divide(BigInteger another) {   
        BigInteger res = new BigInteger();
        int length1 = this.digits.length;   
        int length2 = another.digits.length;
        //位数不相等length1<length2 则为默认值0
        if(length1<length2){}
        //位数相等
        else if(length1==length2){
            int num = 0;//用于位数相等结果
            boolean isAbsoluteEqual = true;//两数是否相同  
            for(int i = 0; i < this.digits.length; i++){   
                if(this.digits[i] != another.digits[i]){      
                    isAbsoluteEqual = false;   
                    break;   
                }   
            }    
            if(isAbsoluteEqual) num = 1; 
            else{//不相同进行减法
            BigInteger temp = new BigInteger();
            temp = this;
                while(temp.sign==true){
                    temp = temp.subtract(another);
                    num++;
                }
                num--;//结果为负数减一
            }
            res.digits[0] = (byte)num;
        }
        //位数this>another
        else{
            BigInteger that = new BigInteger();//this的复制
            that = this;
            int count = length1-length2;
            int[] result = new int[count+1];  

            for(int i=0; i<=count; i++){//count位的循环计算
                BigInteger temp = new BigInteger();
                temp.digits = new byte[length1-i];   
                for(int j=0; j<length2; j++){   //给temp赋值
                    temp.digits[j] = another.digits[j];       
                }
                //减法过程
                int number = 0;//存储一轮减法结果
                while(that.sign==true){
                    that = that.subtract(temp);
                    number++;
                }
                number--;
                that = that.add(temp);
                result[i] = number;   
            }
            //消去前面的0
            int zeroCount = 0;   
            for(int i = 0;i < result.length;i++){   
                if(result[i] == 0){   
                    zeroCount++;   
                }else{   
                    break;   
                }   
            }     
            res.digits = new byte[result.length - zeroCount];   
            for(int i = 0;i < res.digits.length;i++){   
                res.digits[i] = (byte)result[zeroCount + i];   
            }   
        }       
        return res;
    } 


    public BigInteger divide(int num) {   
        return this.divide(new BigInteger(num)); 
    } 

实现了数据类型及相关的函数,接下来就是实现相关题目要求,即对输入的字符串的合法性进行检验,在进行四则运算,所以重新写了类Compute里面调用之前写的数据类型BigInteger来实现长正整数四则运算,代码如下:

//import java.math.BigInteger;math包里自带的BigInteger
//直接使用自己编写在同一个包里的BigInteger
public class Compute {
    //检验字符串
    public static boolean Check(String s){
        int num = 0;
        for(int i = 0; i<s.length(); i++){
            //检查是否存在非法字符
            if(s.charAt(i)-'0' < 0 || s.charAt(i)-'0' > 9){
                return false;
            }
            //检查是否为正整数
            if(s.charAt(i)=='0'){
                num++;
            }
        }
        if(num == s.length()) return false;
        else return true;
    }
    //加法
    public static String Add(String s1, String s2){
        if(Check(s1)&&Check(s2)){
            BigInteger n1 = new BigInteger(s1);
            BigInteger n2 = new BigInteger(s2);
            String ret = n1.add(n2).toString();
            return ret;
        }
        else return String.valueOf(false);
    }
    //减法
    public static String Subtract(String s1, String s2){
        if(Check(s1)&&Check(s2)){
            BigInteger n1 = new BigInteger(s1);
            BigInteger n2 = new BigInteger(s2);
            String ret = n1.subtract(n2).toString();
            return ret;
        }
        else return String.valueOf(false);
    }   
    //乘法
    public static String Multiply(String s1, String s2){
        if(Check(s1)&&Check(s2)){
            BigInteger n1 = new BigInteger(s1);
            BigInteger n2 = new BigInteger(s2);
            String ret = n1.multiply(n2).toString();
            return ret;
        }
        else return String.valueOf(false);
    }

    //除法
    public static String Divide(String s1, String s2){
        if(Check(s1)&&Check(s2)){
            BigInteger n1 = new BigInteger(s1);
            BigInteger n2 = new BigInteger(s2);
            String ret = n1.divide(n2).toString();
            return ret;
        }
        else return String.valueOf(false);
    }

    public static void main(String args[])
    {
        String s1 = new String("10000000000000000000000000000");
        String s2 = new String("100000000000000123");
        String s3 = Compute.Divide(s1, s2);
        System.out.println(s3);
    }
}

测试的话可以使用Junit 实用的教程http://blog.csdn.net/shenpibaipao/article/details/78590749http://blog.csdn.net/andycpp/article/details/1327147/


import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.After;
import org.junit.Test;
import org.junit.Ignore;

public class ComputeTest {
    @Before
    public void before() throws Exception {
    }
    @After
    public void after() throws Exception {  
        System.out.println();
    } 
    @Test
    public void testAdd() throws Exception {
        System.out.println("开始测试加法");
        String[] a = new String[]{"a88888","6549876541649875487989121364"};
        String[] b = new String[]{"888888","9854225774125485623215"};
        String[] c = new String[]{"false","6549886395875649613474744579"};
        for(int i = 0; i<a.length; i++){
            assertEquals(c[i],Compute.Add(a[i], b[i]));
            System.out.println(a[i]+" + "+b[i]+"\n预期结果:"+c[i]+"\n运行结果:"+Compute.Add(a[i], b[i]));
        }
    }

    @Test
    public void testSubtract() {
        System.out.println("开始测试减法");
        String[] a = new String[]{"a88888","6549876541649875487989121364"};
        String[] b = new String[]{"888888","9854225774125485623215"};
        String[] c = new String[]{"false","6549866687424101362503498149"};

        for(int i = 0; i<a.length; i++) {
            assertEquals(c[i],Compute.Subtract(a[i], b[i]));
            System.out.println(a[i]+" - "+b[i]+"\n预期结果:"+c[i]+"\n运行结果:"+Compute.Subtract(a[i], b[i]));
        }
    }

    @Test
    public void testMultiply() {
        System.out.println("开始测试乘法");
        String[] a = new String[]{"a88888","6549876541649875487989121364"};
        String[] b = new String[]{"888888","9854225774125485623215"};
        String[] c = new String[]{"false","64543962234066102857443470706680302877501810865260"};
        for(int i = 0; i<a.length; i++){
            assertEquals(c[i],Compute.Multiply(a[i], b[i]));
            System.out.println(a[i]+" * "+b[i]+"\n预期结果:"+c[i]+"\n运行结果:"+Compute.Multiply(a[i], b[i]));
        }
    }

    @Test
    public void testDivide() {
        System.out.println("开始测试除法");
        String[] a = new String[]{"a88888","6549876541649875487989121364"};
        String[] b = new String[]{"888888","9854225774125485623215"};
        String[] c = new String[]{"false","664676"};
        for(int i = 0; i<a.length; i++){
            assertEquals(c[i],Compute.Divide(a[i], b[i]));
            System.out.println(a[i]+" / "+b[i]+"\n预期结果:"+c[i]+"\n运行结果:"+Compute.Divide(a[i], b[i]));
        }
    }

}

PS:这是第一次写博客,很有新鲜感,主要就是觉得在网上有许多大佬的分享让我受益良多,因此就想把自己的收获总结一下,方便记忆。慢慢来吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值