zoukankan      html  css  js  c++  java
  • Java大数乘法的简单实现(整数和浮点数的乘法)

    大数乘法可以进行任意大小和精度的整数和浮点数的乘法运算, 精确度很高, 可以用作经融等领域的计算.

    这个是我看了一些资料, 然后自己整理实现的. 简单测试了一下.

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    /**
     * 大数乘法的简单实现, 目前还不是很完善
     * Fix: 
     * 1. 修改前后删除0的一些错误情况
     * 2. 支持负数运算
     * 3. 判断输入字符串是否符合小数定义, 用正则表达式判断
     * @author icejoywoo
     * @since 2012.2.16
     * @version 0.1.1
     */
    public class BigNumber {
    	public static void main(String[] args) throws IOException {
    		System.out.println("Input two large integers:");
    		BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in));
    		String[] strArray = buffer.readLine().split("\\*");
    		System.out.println(bigNumberMultiply(strArray[0], strArray[1]));
    	}
    	
    	/**
    	 * 计算两个任意大小和精度的数的乘积
    	 * @param first 第一个参数
    	 * @param second 第二个参数
    	 * @return 两个数的乘积
    	 */
    	private static String bigNumberMultiply(String first, String second) {
    		// 正负号判断标志
    		boolean flag = false;
    		
    		if (first.charAt(0) == '-') {
    			flag = !flag;
    			first = first.substring(1);
    		}
    		
    		if (second.charAt(0) == '-') {
    			flag = !flag;
    			second = second.substring(1);
    		}
    		
    		// 小数点的位置
    		int aPoints = first.length() - first.indexOf('.') - 1;
    		int bPoints = second.length() - second.indexOf('.') - 1;
    		int pointPos = aPoints + bPoints; // 结果的小数点位置
    		
    		// 删除小数点
    		StringBuffer aBuffer = new StringBuffer(first.replaceAll("\\.", ""));
    		StringBuffer bBuffer = new StringBuffer(second.replaceAll("\\.", ""));
    		
    		int[] a = string2IntArray(aBuffer.toString());
    		int[] b = string2IntArray(bBuffer.toString());
    		
    		int[] result = new int[a.length + b.length - 1]; // 保存结果的数组
    		
    		// 计算
    		for (int i = 0; i < a.length; i++) {
    			for (int j = 0; j < b.length; j++) {
    				result[i + j] += a[i] * b[j];
    			}
    		}
    		
    		// result中的某一位大于9的话需要进位
    		for (int i = result.length - 1; i >= 0; --i) {
    			if (result[i] > 9) {
    				result[i - 1] += result[i] / 10;
    				result[i] = result[i] % 10;
    			}
    		}
    		
    		StringBuffer buffer = new StringBuffer(); // 将result数组转换为字符串
    		for (int i = 0; i < result.length; ++i) {
    			// 添加小数点
    			if(result.length - i == pointPos) {
    				buffer.append(".");
    			}
    			buffer.append(String.valueOf(result[i]));
    		}
    		
    		if (buffer.indexOf(".") != -1)
    		{
    			// 删除最开始的0
    			int i = 0;
    			while (i < buffer.length()) {
    				if (buffer.length() > 2 && buffer.charAt(i+1) == '.') { // 小数点前只有一个数 0.
    					break;
    				} else if (buffer.charAt(i) == '0') { // 删除最前边的0
    					buffer.deleteCharAt(i);
    					i = 0;
    					continue;
    				} else { // 当第一位不是0的时候
    					break;
    				}
    			}
    
    			// 删除末尾的0
    			i = buffer.length() - 1;
    			while (i >= 0) {
    				if (buffer.length() > 2 && buffer.charAt(i-1) == '.') { // 小数点后直接是数字
    					break;
    				} else if (buffer.charAt(i) == '0') { // 删除末尾的0
    					buffer.deleteCharAt(i);
    					i = buffer.length() - 1;
    					continue;
    				} else { // 当最后一位不是0的时候
    					break;
    				}
    			}
    		}
    		
    		// 根据符号位, 返回值的正负标志
    		if (flag) {
    			return "-" + buffer.toString();
    		} else {
    			return buffer.toString();
    		}
    	}
    	
    	/**
    	 * 将字符串装换为数组
    	 * @param number
    	 * @return
    	 */
    	private static int[] string2IntArray(String number) {
    		// 判断输入是否符合浮点数的要求
    		Pattern pattern = Pattern.compile("^(-?\\d+|\\d*)\\.?\\d*$");
    		Matcher matcher = pattern.matcher(number);
    		if (!matcher.find()) {
    			throw new IllegalArgumentException("输入的数不正确!");
    		}
    		
    		int[] result = new int[number.length()];
    		for (int i = 0; i < number.length(); i++) {
    			result[i] = (int) (number.charAt(i) - '0');
    		}
    		return result;
    	}
    }
    

     运行结果如下:

    1. 错误输入的判断

    Input two large integers:
    1a*a22
    Exception in thread "main" java.lang.IllegalArgumentException: 输入的数不正确!
    	at BigNumber.string2IntArray(BigNumber.java:132)
    	at BigNumber.bigNumberMultiply(BigNumber.java:54)
    	at BigNumber.main(BigNumber.java:22)
    

     2. 带负数的运算, 前后带有0的情况

    Input two large integers:
    -23424.2300*02345.23400000
    -54935300.61982
    

     python中计算的结果如下

    Python 2.6.5 
    >>> -23424.2300*02345.23400000
    -54935300.619819999
    

     可以看出python的结果是有失真的

  • 相关阅读:
    位运算符设置权限
    urlencode、urldecode、rawurlencode、rawurldecod
    二分查找法的mid值 整数溢出问题
    GIT 常用命令
    nginx配置反向代理转发
    PHP实现无限极分类
    PHP面试题目整理(持续更新)
    去除input的默认样式
    git 常用指令
    数组去重
  • 原文地址:https://www.cnblogs.com/icejoywoo/p/2354350.html
Copyright © 2011-2022 走看看