前言
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