JS实现大整数乘法(性能优化、正负整数)

本方法的思路为:

  一:检查了输入的合法性(非空,无非法字符)

  二:检查输入是否可以进行简单计算(一个数为 0,1,+1,-1)

  三:去掉输入最前面可能有的正负符号,并判断输出的正负

  四:将输入的值分成4位一截(分的长度太短,性能太差,长度太长,精度容易降低)

  五:遍历相乘得到最终数组(这里用了递归)

  六:遍历最终数组,拼接最终的数(不建议用join,因为数组中的元素可能小于四位,拼接时会丢失0)

  七:将正负符号与最终的数拼接输出

代码如下:

 

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script type="text/javascript">
        var num1 = "";
        var num2 = "";
        var finallyArr;
        /*
         * 有两个用字符表示的非常大的大整数,算出他们的乘积,也是用字符串表示,不能用系统自带的大整数类型。
         * 输入例子72106547548473106236 982161082972751393
         * 输出例子70820244829634538040848656466105986748
                    70820244829634538040848656466105986748
         */
        function getResult(){
            finallyArr = new Array();
             num1 = document.getElementById("num1").value;
             num2 = document.getElementById("num2").value;         
             if(!checkNum(num1)){
                 alert("输入:num1 不合法!");
                 return;
             }
             if(!checkNum(num2)){
                 alert("输入:num2 不合法!");
                 return;
             }
             //特殊情况的简单算法
             if(doSimpleWay()){
                 return;
             }
             
             //获取最终值的正负符号
             var symbol = initSymbol();
             
             //将输入的值分成4位一小截的数组
             var numArr1 = getNumArr(num1,new Array());
             var numArr2 = getNumArr(num2,new Array());
             
             //遍历相乘相加得到最终的数组
             for(var i = 0; i < numArr1.length; i++){
                 for(var j = 0; j < numArr2.length; j++){
                     updateFinallyArr(i + j , numArr1[i] * numArr2[j]);                     
                 }
             }
             //倒序遍历数组获取最终结果
             var resultStr = finallyArr.pop();
             for(var i = finallyArr.length; i >= 0; i--){
                 if(finallyArr[i] >= 1000){
                     resultStr +=  "" + finallyArr[i];
                 }else if(finallyArr[i] < 1000){
                     resultStr += "0" + finallyArr[i];
                 }else if(finallyArr[i] < 100){
                     resultStr += "00" + finallyArr[i];
                 }else if(finallyArr[i] < 10){
                     resultStr += "000" + finallyArr[i];
                 }else if(finallyArr[i] == 0){
                     resultStr += "0000";
                 }
             }
             document.getElementById("RESULT").innerText = symbol + resultStr;
        }

        /**
         * 根据数值以及数值的位置更新最终的数组
         */
        function updateFinallyArr(i , num){
            var old = finallyArr[i];
            if(old){
                num = num + old;
            }
            if(num > 9999){
                finallyArr[i] = num % 10000;
                updateFinallyArr(i + 1 , Math.floor(num/10000) );
            }else{
                finallyArr[i] = num;
            }

        }

        /**
         * 处理输入字符串的正负号,并判断最终值的正负号
         */
        function initSymbol(){
            if(num1.substring(0,1) == "-"){
                 num1 = num1.substring(1,num1.length); 
                 if(num2.substring(0,1) == "-"){
                     num2 = num2.substring(1,num2.length);
                 }else if(num2.substring(0,1) == "+"){
                     num2 = num2.substring(1,num2.length);
                     return "-";
                 }else{
                     return "-";
                 }
             }else if(num1.substring(0,1) == "+"){
                 num1 = num1.substring(1,num1.length); 
                 if(num2.substring(0,1) == "-"){
                     num2 = num2.substring(1,num2.length);
                     return "-";
                 }else if(num2.substring(0,1) == "+"){
                     num2 = num2.substring(1,num2.length); 
                 }
             }
             return "";
        }

        /**
         * 特殊情况的简单算法
         */
        function doSimpleWay(){
            if(num1 == "0" || num2 == "0"){
                document.getElementById("RESULT").innerText = "0";
                 return true;
             }else if(num1 == "1" || num1 == "+1"){
                 document.getElementById("RESULT").innerText = num2;
                 return true;
             }else if(num2 == "1" || num2 == "+1"){
                 document.getElementById("RESULT").innerText = num1;
                 return true;
             }else if(num1 == "-1"){
                 if(num2.substring(0,1) == "-" ){
                     document.getElementById("RESULT").innerText = num2.substring(1,num2.length);
                 }else if(num2.substring(0,1) == "+" ){
                     document.getElementById("RESULT").innerText = "-" + num2.substring(1,num2.length);
                 }else{
                     document.getElementById("RESULT").innerText = "-" + num2;
                 }
                 return true;
             }else if(num2 == "-1"){
                 if(num1.substring(0,1) == "-" ){
                     document.getElementById("RESULT").innerText = num1.substring(1,num1.length);
                 }else if(num1.substring(0,1) == "+" ){
                     document.getElementById("RESULT").innerText = "-" + num1.substring(1,num1.length);
                 }else{
                     document.getElementById("RESULT").innerText = "-" + num1;
                 }
                 return true;
             }
             return false;
        }

        /**
         * 获取4位一小截的数组
         */
        function getNumArr(num,arr){
            var len = num.length;
            if(len > 4){
                arr.push(num.substring(len-4,len) * 1);
                num = num.substring(0,len-4);
                return getNumArr(num,arr);
            }else{
                arr.push(num * 1);
                return arr;
            }
        }

        /**
         * 检查输入数字的正确性,非空、无不合法字符
         */
        function checkNum(num){
             if(!num){
                 return false;
             }
             var str = num.replace(/[0-9]/g,"");
             if(str == "" || (str == "-" && num.substring(0,1) =="-" && num.length > 1) 
                 || (str == "+" && num.substring(0,1) =="+" && num.length > 1) ){
                 if(num.length > 1000){
                     return false;
                 }
                 return true;
             }else{
                 return false;
             }
        }
    </script>
</head>
<body>
    num1:<input type="text" id="num1" name="" 
    value
="7210654754847310623672106547548473106236721065475484731062367210654754847310623672106547548473106236" style="width:80%"></br> num2:<input type="text" id="num2" name=""
    value
="9821610829727513939821610829727513939821610829727513939821610829727513939821610829727513939821610829" style="width:80%"></br> <input type="button" id="num2" value="计算" onclick="getResult()"></br> <textarea id = "RESULT" rows="5" style="width:80%"></textarea> </body> </html>

 

 
posted @ 2018-03-12 15:44  有营养的yyl  阅读(...)  评论(...编辑  收藏