zoukankan      html  css  js  c++  java
  • 两个长数字(非负数,大整数)相除,计算只取整数位,小数位舍去。

         

       计算两个大整数相除的结果,数字不是double类型能表示的,数字长度没有限制(最大127位)。

    方法一:使用java中的大整数处理库函数,java.math.BigInteger,java.math.BigDecimal;

    方法二:不利用库函数,自己实现其功能,可以练习自己对待复杂问题的处理能力,提高编程水平。

    此代码中利于两者的结合,利于库函数可以看自己编写的代码的正确性。

      对于大整数的运算,除法是最难的,因为要考虑到补位的操作,还有商的确定操作。只要把这两个操作看明白

    其他操作只不过是在大整数的基础上进行加减操作,大整数处理特别要注意细节。

    1、下面的方法是本程序中的核心代码,即补位操作和商的确定。注意下面方法中的参数s1大于s2,s1是被除数,s2是除数。

    /*已经判断出s1对于s2,s1大于等于s2*/
    public static String division_first(String s1,String s2){
        int len1=s1.length(),len2=s2.length();
        String str="",st=s1.substring(0,len2);
        int kk=0;
        for(int i=len2-1;i<len1;++i)
        {
            if(kk==0)    
                kk=1;
            else  /*非首次进入要补位*/
            {
                st=st+s1.charAt(i);
                st=take_head_zero(st);
            }
            /*判断st是否小于s2,若小于补位*/
            int sss=0;
            while(!(is_big(st,s2))&&(i<len1))
            {
                 str+="0"; /*别忘了商要不零*/
                int ii=i;
                if(++ii>=len1)
                {
                 sss=1;
                 break;
                }
                else
                {
                    ++i;
                    st=st+s1.charAt(i);
                }
            }
            if(sss==1)
                break;
            /*确定倍数k,即是商的确定。*/
            int k=9;
            String temp="0";
            st=take_head_zero(st);
            for( k=9;k>0;--k)
            {
                temp=multiply_one(s2,k);
                if(is_big(st,temp))
                    break;    
            }
            str=str+k;
            st=integer_sub(st,temp);
            
            st=take_head_zero(st);
        }
        return str;
    };

    2、完整代码

    import java.math.BigDecimal;
    import java.util.Scanner;
    public class Big_division {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
          int i=10;
          while(i>=1){
          System.out.println("---------------------------");
          System.out.println("计算两个大整数相除");
          System.out.print("输入第一个正数:");
          String s1=sc.next();
          System.out.print("输入第二个正数:");
          String s2=sc.next();
          String s4=send(s1,s2);
          System.out.println("  相除结果是:"+s4);
          System.out.println("相除正确结果:"+ku_big(s1,s2));
          --i;
          }
          sc.close();
    };
    public static String send(String s1,String s2){
        if(!(check(s1)&&check(s2)))
         return "输入有非法字符";    
        s1=take_head_zero(s1);
        s2=take_head_zero(s2);
        if(s2.equals("0"))
            return "除数不能为0";
        if(!is_big(s1,s2)) /*先看一下大小*/
         return "0";
        String str=division_first(s1,s2);
        str=take_head_zero(str);
        return str;
    };
    /*已经判断出s1对于s2,s1大于等于s2*/
    public static String division_first(String s1,String s2){
        int len1=s1.length(),len2=s2.length();
        String str="",st=s1.substring(0,len2);
        int kk=0;
        for(int i=len2-1;i<len1;++i)
        {
            if(kk==0)    
                kk=1;
            else  /*非首次进入要补位*/
            {
                st=st+s1.charAt(i);
                st=take_head_zero(st);
            }
            /*判断st是否小于s2,若小于补位*/
            int sss=0;
            while(!(is_big(st,s2))&&(i<len1))
            {
                 str+="0"; /*别忘了商要不零*/
                int ii=i;
                if(++ii>=len1)
                {
                 sss=1;
                 break;
                }
                else
                {
                    ++i;
                    st=st+s1.charAt(i);
                }
            }
            if(sss==1)
                break;
            /*确定倍数k,即是商的确定。*/
            int k=9;
            String temp="0";
            st=take_head_zero(st);
            for( k=9;k>0;--k)
            {
                temp=multiply_one(s2,k);
                if(is_big(st,temp))
                    break;    
            }
            str=str+k;
            st=integer_sub(st,temp);
            
            st=take_head_zero(st);
        }
        return str;
    };
    /*两个整数相减*/
    public static String integer_sub(String s1,String s3){
        int max=s1.length(),min=s3.length(),i=0;
        String str="";
        i=1;
        int k=0,before=0;
        while(i<=max){
            if(i<=min)
                k=s1.charAt(max-i)-s3.charAt(min-i)-before;
            else
                k=s1.charAt(max-i)-'0'-before;
            if(k<0)
            {
                k+=10;
                before=1;
            }else
                before=0;
            str=k+str;
            ++i;
        }
        return str;
    };
    /*将s乘以a返回结果*/
    public static String multiply_one(String s,int a){
        int len=s.length(),k=0,before=0,kk=0;
        String str="";
        for(int i=1;i<=len;++i) /*从最低位(即下标最大)处开始算*/
        {
            k=(s.charAt(len-i)-'0')*a+before; 
            before=k/10;
            k=k%10;
            str=k+str;
            kk=1;
        }
        if(kk==0)
            str="0";
        else
         if(before>0)
            str=before+str;
        return str;
    };
    /*当s1大于等于s2时返回true,否则返回false。*/
    public static boolean is_big(String s1,String s2){
        s1=take_head_zero(s1);
        s2=take_head_zero(s2);
        if(s1.length()>s2.length())
            return true;
        else
        {
            if(s1.length()<s2.length())
                return false;
            else
            {
                int k=0;
                for(int i=0;i<s1.length();++i)
                {
                     k=s1.charAt(i)-s2.charAt(i);
                     if(k==0)
                         continue;
                     
                    if(k>0)
                        return true;
                    else
                        return false;
                }
            }
        }
        return true;
    };
    public static String integer_add(String s1,String s2){ 
        /*传递的时候已经确定第一个参数s1为最长字符串,s2为短字符串。*/
        if(s1.length()<s2.length())
        {
            String temp=s1;
            s1=s2;
            s2=temp;
        }
        int len1=s1.length(),len2=s2.length();
        int a,temp=0;
        String str="";
        for(int i=1;i<=len1;++i) 
        /*注意开始i=1,结束时i==len1,因为前面i是从1开始,后面结束要多算一位*/
        {
            if(i<=len2)
               a=temp+(s1.charAt(len1-i)-'0')+(s2.charAt(len2-i)-'0');
            else
                a=temp+(s1.charAt(len1-i)-'0');
            temp=a/10;
            a=a%10;
            str=a+str;
        }
        if(temp!=0)
            str=temp+str;
        /*消除最前面的数字0*/
        str=take_head_zero(str);
        return str;
    };
    /*剔除前面多余的数字0.*/
    public static String take_head_zero(String s){
        int len=s.length(),i=0;
        while(i<len)
        {
            if(s.charAt(i)=='0')
                ++i;
            else
                break;
        }
        if(i<len)
         s=s.substring(i);
        else
            s="0";
        return s;
    };
    public static boolean check(String s){
        int k=0;
        for(int i=0;i<s.length();++i)
        {
            if(s.charAt(i)<='9'&&s.charAt(i)>='0')
            {
                if(s.charAt(i)=='.')
                {    ++k;
                  if(k>=2)
                    return false;
                }
            }
            else
                return false;
        }
        return true;
    };
    public static String ku_big(String s1,String s2){
        BigDecimal b1;
        BigDecimal b2;
        BigDecimal b=new BigDecimal("0");
       try{
        b1=new BigDecimal(s1);  
        b2=new BigDecimal(s2);
        b=b1.divide(b2,1); /*数字1指明roundingMode - 要应用的舍入模式。*/
        
        }catch(Exception e){
            //System.out.println(e);
            return "输入有非法字符";
        }
        return b.toString();
    };
    
    }
  • 相关阅读:
    (转)C# DllImport的用法
    (转)C#网络编程(异步传输字符串) Part.3
    (转)C#网络编程(订立协议和发送文件) Part.4
    C# tostring()汇总
    (转)C#网络编程(基本概念和操作) Part.1
    (转)关于数据库存储过程分页DatagridView BindingNavigator 控件的详细实现
    C# sql server 数据库备份和还原
    (转)C#网络编程(接收文件) Part.5
    2010年5月学习计划
    APUE学习笔记 Chapter 2 . Unix Standardization and Implementations
  • 原文地址:https://www.cnblogs.com/duange/p/5999254.html
Copyright © 2011-2022 走看看