calculate-asmd
Advanced tools
Comparing version 2.0.0 to 3.0.0
161
index.js
"use strict"; | ||
/** | ||
加法 | ||
**/ | ||
* [scaleNum 通过操作其字符串将一个浮点数放大或缩小] | ||
* @param {number} num 要放缩的浮点数 | ||
* @param {number} pos 小数点移动位数 | ||
* pos大于0为放大,小于0为缩小;不传则默认将其变成整数 | ||
* @return {number} 放缩后的数 | ||
*/ | ||
function scaleNum(num, pos) { | ||
if (num === 0 || pos === 0) { | ||
return num; | ||
} | ||
let absNum = num; | ||
let s = 1; | ||
if (num < 0) { | ||
absNum = Math.abs(num); | ||
s = -1; | ||
} | ||
let parts = absNum.toString().split("."); | ||
const intLen = parts[0].length; | ||
const decimalLen = parts[1] ? parts[1].length : 0; | ||
// 默认将其变成整数,放大倍数为原来小数位数 | ||
if (pos === undefined || pos === null) { | ||
return parseFloat(parts[0] + parts[1]); | ||
} else if (pos > 0) { | ||
// 放大 | ||
let zeros = pos - decimalLen; | ||
while (zeros > 0) { | ||
zeros -= 1; | ||
parts.push(0); | ||
} | ||
} else { | ||
// 缩小 | ||
let zeros = Math.abs(pos) - intLen; | ||
while (zeros > 0) { | ||
zeros -= 1; | ||
parts.unshift(0); | ||
} | ||
} | ||
const idx = intLen + pos; | ||
parts = parts.join("").split(""); | ||
parts.splice(idx > 0 ? idx : 0, 0, "."); | ||
if (s < 0) { | ||
parts.unshift("-"); | ||
} | ||
return parseFloat(parts.join("")); | ||
} | ||
/** | ||
* [add 通过比较两个加数谁的小数位最大,将两数小数点右移为整数进行计算] | ||
* @param {number} arg1 加数 | ||
* @param {number} arg2 被加数 | ||
* @return {number} 结果 | ||
*/ | ||
function add(arg1, arg2) { | ||
var r1 = 0; | ||
var r2 = 0; | ||
var m = 0; | ||
let r1 = 0; | ||
let r2 = 0; | ||
let scale = 0; | ||
try { | ||
@@ -21,4 +77,7 @@ r1 = arg1.toString().split(".")[1].length; | ||
m = Math.pow(10, Math.max(r1, r2)); | ||
var result = (arg1 * m + arg2 * m) / m; | ||
scale = Math.max(r1, r2); | ||
const num1 = scaleNum(arg1, scale); | ||
const num2 = scaleNum(arg2, scale); | ||
const num = num1 + num2; | ||
const result = scaleNum(num, -scale); | ||
return result; | ||
@@ -28,8 +87,11 @@ } | ||
/** | ||
减法 | ||
**/ | ||
* [sub 通过比较两个加数谁的小数位最大,将两数小数点右移为整数进行计算] | ||
* @param {number} arg1 减数 | ||
* @param {number} arg2 被减数 | ||
* @return {number} 结果 | ||
*/ | ||
function sub(arg1, arg2) { | ||
var r1 = 0; | ||
var r2 = 0; | ||
var m = 0; | ||
let r1 = 0; | ||
let r2 = 0; | ||
let scale = 0; | ||
try { | ||
@@ -47,4 +109,7 @@ r1 = arg1.toString().split(".")[1].length; | ||
m = Math.pow(10, Math.max(r1, r2)); | ||
var result = (arg1 * m - arg2 * m) / m; | ||
scale = Math.max(r1, r2); | ||
const num1 = scaleNum(arg1, scale); | ||
const num2 = scaleNum(arg2, scale); | ||
const num = num1 - num2; | ||
const result = scaleNum(num, -scale); | ||
return result; | ||
@@ -54,53 +119,67 @@ } | ||
/** | ||
乘法 | ||
**/ | ||
* [mul 将两个浮点数参数replace掉小数点为整数计算,scale在这里进行累计小数位] | ||
* @param {number} arg1 乘数 | ||
* @param {number} arg2 被乘数 | ||
* @return {number} 结果 | ||
*/ | ||
function mul(arg1, arg2) { | ||
var r1 = Number(arg1.toString().replace(".", "")); | ||
var r2 = Number(arg2.toString().replace(".", "")); | ||
var m = 0; | ||
const num1 = Number(arg1.toString().replace(".", "")); | ||
const num2 = Number(arg2.toString().replace(".", "")); | ||
let scale = 0; | ||
try { | ||
m += arg1.toString().split(".")[1].length; | ||
scale += arg1.toString().split(".")[1].length; | ||
} catch (e) { | ||
m += 0; | ||
scale += 0; | ||
} | ||
try { | ||
m += arg2.toString().split(".")[1].length; | ||
scale += arg2.toString().split(".")[1].length; | ||
} catch (e) { | ||
m += 0; | ||
scale += 0; | ||
} | ||
var result = (r1 * r2) / Math.pow(10, m); | ||
const num = num1 * num2; | ||
const result = scaleNum(num, -scale); | ||
return result; | ||
} | ||
/** | ||
除法 | ||
**/ | ||
/** | ||
* [div 将两个浮点数参数replace掉小数点为整数计算,scale是被除数与除数的移动位数差] | ||
* @param {number} arg1 除数 | ||
* @param {number} arg2 被除数 | ||
* @return {number} 结果 | ||
*/ | ||
function div(arg1, arg2) { | ||
var r1 = Number(arg1.toString().replace(".", "")); | ||
var r2 = Number(arg2.toString().replace(".", "")); | ||
var l1 = 0; | ||
var l2 = 0; | ||
const num1 = Number(arg1.toString().replace(".", "")); | ||
const num2 = Number(arg2.toString().replace(".", "")); | ||
let left1 = 0; | ||
let left2 = 0; | ||
try { | ||
l1 = Number(arg1.toString().split(".")[1].length); | ||
left1 = Number(arg1.toString().split(".")[1].length); | ||
} catch (e) { | ||
l1 = 0; | ||
left1 = 0; | ||
} | ||
try { | ||
l2 = Number(arg2.toString().split(".")[1].length); | ||
left2 = Number(arg2.toString().split(".")[1].length); | ||
} catch (e) { | ||
l2 = 0; | ||
left2 = 0; | ||
} | ||
var pow = Math.pow(10, Math.max(l1, l2)); | ||
//var result = (Number(r1) / Number(r2)) * Math.pow(10, l2 - l1); 这样也会出现精度问题 | ||
/** | ||
* 当被除数100是整数没有移动小数位,那么left2为0,除数0.57在运算中转整数为57。 | ||
* 在实际的运算中0.57除以100中的0.57是根据被除数来移动小数的。 | ||
* 所以,0 - 2 = -2。 将运算结果缩小两位为实际小数点位置 | ||
* | ||
* 除数多拿了被除数的几口口粮,最后要还回去的。 | ||
* | ||
*/ | ||
const scale = left2 - left1; | ||
const num = num1 / num2; | ||
//先把结果放大一定倍数,再去移动相应位数 | ||
var result = r1 / r2; | ||
result = (result * pow * Math.pow(10, l2 - l1)) / pow; | ||
const result = scaleNum(num, scale); | ||
return result; | ||
} | ||
module.exports = { add, sub, mul, div }; | ||
module.exports = { add, sub, mul, div, scaleNum }; |
{ | ||
"name": "calculate-asmd", | ||
"version": "2.0.0", | ||
"version": "3.0.0", | ||
"description": "加减乘除四则运算(calculate/arithmetic)", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -7,5 +7,3 @@ # calculate-asmd | ||
1. 浮点数值的最高进度是 17 位小数,但在进行运算的时候其精确度却远远不如整数;整数在进行运算的时候都会转成 10 进制。 | ||
2. Java 和 JavaScript 中计算小数运算时,都会先将十进制的小数换算到对应的二进制,一部分小数并不能完整的换算为二进制,这里就出现了第一次的误差。 | ||
3. 待小数都换算为二进制后,再进行二进制间的运算,得到二进制结果。然后再将二进制结果换算为十进制,这里通常会出现第二次的误差。 | ||
[浮点数运算 0.2 + 0.4 = 0.6 ?](https://github.com/sanshuiwang/Blog/issues/9) | ||
@@ -28,24 +26,42 @@ > 使用 | ||
/** 加法 */ | ||
const addNum = add(9.9, 0.2); | ||
console.log("add: ", addNum); | ||
const addNum = add(0.2, 0.4); | ||
console.log("add(0.2, 0.4): ", addNum); | ||
const addNegative = add(0.2, -0.4); | ||
console.log("add(0.2, -0.4): ", addNegative); | ||
/** | ||
*add(0.2, 0.4): 0.6 | ||
*add(0.2, -0.4): -0.2 | ||
*/ | ||
/** 减法 */ | ||
const subNum = sub(9.9, 0.2); | ||
console.log("sub: ", subNum); | ||
const subNum = sub(0.2, 0.4); | ||
console.log("sub(0.2, 0.4): ", subNum); | ||
const subNegative = sub(0.2, -0.4); | ||
console.log("sub(0.2, -0.4): ", subNegative); | ||
/** | ||
*sub(0.2, 0.4): -0.2 | ||
*sub(0.2, -0.4): 0.6 | ||
*/ | ||
/** 乘法 */ | ||
const mulNum = mul(9.9, 0.2); | ||
console.log("mul: ", mulNum); | ||
const mulNum = mul(0.57, 100); | ||
console.log("mul(0.57, 100): ", mulNum); | ||
const mulNegativ = mul(-0.57, 100); | ||
console.log("mul(-0.57, 100): ", mulNegativ); | ||
/** | ||
*mul(0.57, 100): 57 | ||
*mul(-0.57, 100): -57 | ||
*/ | ||
/** 除法 */ | ||
const divNum = div(9.9, 0.2); | ||
console.log("div: ", divNum); | ||
const divNum = div(0.57, 100); | ||
console.log("div(0.57, 100): ", divNum); | ||
const divNegative = div(-0.57, 100); | ||
console.log("div(-0.57, 100): ", divNegative); | ||
/** | ||
*div(0.57, 100): 0.0057 | ||
*div(-0.57, 100): -0.0057 | ||
*/ | ||
``` | ||
> 参考 | ||
[精确四则运算](https://blog.csdn.net/u010004317/article/details/79009172) | ||
[js 小数运算出现多位小数如何解决 | ||
](http://www.cnblogs.com/zdz8207/p/js-number-tofixed.html) |
@@ -1,12 +0,29 @@ | ||
const { add, sub, mul, div } = require("../index.js"); | ||
const { add, sub, mul, div, scaleNum } = require("../index.js"); | ||
try { | ||
const addNum = add(9.9, 0.2); | ||
console.log("add: ", addNum); | ||
const subNum = sub(9.9, 0.2); | ||
console.log("sub: ", subNum); | ||
const addNum = add(0.2, 0.4); | ||
console.log("add(0.2, 0.4): ", addNum); | ||
const addNegative = add(0.2, -0.4); | ||
console.log("add(0.2, -0.4): ", addNegative); | ||
const mulNum = mul(9.9, 0.2); | ||
console.log("mul: ", mulNum); | ||
const divNum = div(9.9, 0.2); | ||
console.log("div: ", divNum); | ||
const subNum = sub(0.2, 0.4); | ||
console.log("sub(0.2, 0.4): ", subNum); | ||
const subNegative = sub(0.2, -0.4); | ||
console.log("sub(0.2, -0.4): ", subNegative); | ||
const mulNum = mul(0.57, 100); | ||
console.log("mul(0.57, 100): ", mulNum); | ||
const mulNegativ = mul(-0.57, 100); | ||
console.log("mul(-0.57, 100): ", mulNegativ); | ||
const divNum = div(0.57, 100); | ||
console.log("div(0.57, 100): ", divNum); | ||
const divNegative = div(-0.57, 100); | ||
console.log("div(-0.57, 100): ", divNegative); | ||
console.log(""); | ||
console.log("scaleNum(0.57,2):", scaleNum(0.57, 2)); | ||
console.log("scaleNum(-0.57,-2):", scaleNum(-0.57, -2)); | ||
console.log("scaleNum(0.57,-2):", scaleNum(0.57, -2)); | ||
console.log("scaleNum(-0.57,2):", scaleNum(-0.57, 2)); | ||
} catch (error) { | ||
@@ -13,0 +30,0 @@ console.error("error: ", error); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
8426
5
187
66