java大数乘法的简单实现 浮点数乘法运算

 更新时间:2014年01月20日 11:22:56   作者:  
大数乘法可以进行任意大小和精度的整数和浮点数的乘法运算, 精确度很高, 可以用作经融等领域的计算,这个是我看了一些资料, 然后自己整理实现的,简单测试了一下

复制代码 代码如下:

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的结果是有失真的

相关文章

  • Java线程实现的三种方式详细解析

    Java线程实现的三种方式详细解析

    这篇文章主要介绍了Java线程实现的三种方式详细解析,Java多线程实现方式主要有三种,继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程,需要的朋友可以参考下
    2023-12-12
  • java递归与非递归实现扫描文件夹下所有文件

    java递归与非递归实现扫描文件夹下所有文件

    这篇文章主要为大家详细介绍了java递归与非递归实现扫描文件夹下所有文件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-02-02
  • java中并发Queue种类与各自API特点以及使用场景说明

    java中并发Queue种类与各自API特点以及使用场景说明

    这篇文章主要介绍了java中并发Queue种类与各自API特点以及使用场景说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • java正则表达式匹配规则超详细总结

    java正则表达式匹配规则超详细总结

    正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别,下面这篇文章主要给大家介绍了关于java正则表达式匹配规则的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-10-10
  • Netty中解码器的作用及实现详解

    Netty中解码器的作用及实现详解

    这篇文章主要介绍了Netty中解码器的作用及实现详解,本章我们只需要让客户端发送消息的时候循环发送100次,服务端不变,看看服务端是不是接收到了100条消息,需要的朋友可以参考下
    2023-12-12
  • 专属于程序员的浪漫-Java输出动态闪图iloveyou

    专属于程序员的浪漫-Java输出动态闪图iloveyou

    这篇文章主要介绍了专属于程序员的浪漫-Java输出动态闪图iloveyou,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • 解决MyEclipse下启动项目时JBoss内存溢出的问题

    解决MyEclipse下启动项目时JBoss内存溢出的问题

    下面小编就为大家带来一篇解决MyEclipse下启动项目时JBoss内存溢出的问题。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • Spring条件注解@ConditionnalOnClass的原理分析

    Spring条件注解@ConditionnalOnClass的原理分析

    这篇文章主要介绍了Spring条件注解@ConditionnalOnClass的原理分析,所谓@ConditionalOnClass注解,翻译过来就是基于class的条件,它为所标注的类或方法添加限制条件,当该条件的值为true时,其所标注的类或方法才能生效,需要的朋友可以参考下
    2023-12-12
  • Spring IOC容器Bean注解创建对象组件扫描

    Spring IOC容器Bean注解创建对象组件扫描

    这篇文章主要为大家介绍了Spring IOC容器Bean注解创建对象组件扫描,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05
  • Java异常继承结构解析_动力节点Java学院整理

    Java异常继承结构解析_动力节点Java学院整理

    这篇文章主要介绍了Java异常继承结构解析的相关知识,需要的朋友可以参考下
    2017-04-04

最新评论