大整数加法库实现

573 阅读2分钟
前言

JavaScript中遵循IEEE 754标准采用64位来表示一个数字,即第一个符号位,后面11个表示指数部分,最后52个表示小数部分,即有效数字。因为二进制表示有效数字是以1.xxxx的形式,尾数部分在规约的形势下第一位默认为1,也就是说JavaScript提供的有效数字最长就是53个二进制位,即64位浮点数的后52位+被省略的1位。

所以JavaScript中最大的数字就是2^53-1,Number对象上有个属性,Number. MAX_VALUE 来表示,一旦运算超过这个值,就会出现精度丢失。如果要实现很大的整数加法运算,就需要特定的算法。
接下来实现一个大整数加法运算,并且通过webpack打包成一个库,可以通过模块导入。

功能实现
function add(a, b){
    let i = a.length -1;
    let j = b.length -1;

    let carry = 0;
    let ret = '';
    while (i >= 0 || j >= 0){
        let x = 0;
        let y = 0;
        let sum

        if(i >= 0){
            x = a[i] - '0';
            i --;
        }

        if(j >= 0){
            y = b[j] - '0';
            j --;
        }

        sum = x + y + carry

        if(sum >= 10){
            carry = 1
            sum -=10
        }else{
            carry = 0
        }

        ret = sum + ret
    }

    if(carry){
        ret = carry + ret;
    }

    return ret
}

这里依次从最后一个位相加,如果没有就默认为0,相加后如果sum大于10,就标记carry=1,字符串ret为记录相加的结果,按位相加。加到最后再ret字符串加上carry即是最终结果。

测试一下:

console.log(add('123','321'))
// 444
打包

新建webpack.config,js

const TerserPlugin = require('terser-webpack-plugin')

module.exports = {
    entry: {
        'large-number': './src/index.js',
        'large-number.min': './src/index.js'
    },
    output: {
        filename: '[name].js',
        library: {
            name: 'largeadd',
            type: 'commonjs',
        },
    },
    mode: 'none',
    optimization: {
        minimize: true,
        minimizer: [
            new TerserPlugin({
                include: /\.min\.js$/,
            })
        ]
    }
}

这里打了两个包,一个是压缩的版本,一个是未压缩的版本,在output出口中设置library中的name指定库的名称,设置type指定将库暴露的方式。最后取消webpack 的默认压缩,根据插件来指定有文件名称有.min的才会压缩。

package,json中添加index.js和指定打包命令

"main": "index.js",
...
"build": "webpack",

index.js中返回不同的包

if(process.env.NODE_ENV == 'production'){
    module.exports = require('./dist/large-number.min.js')
}else{
    module.exports = require('./dist/large-number.js')
}
发布

npm官网注册一个账号,在命令行登录npm login,输完账号和密码邮箱,运行npm publish即完成发布

验证

安装模块npm install largeadd

新建文件index.js

let largeNumber = require('largeadd')

console.log(largeNumber.largeadd('123','321'))
//444

代码地址