In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
This article shares with you the content of an example analysis of any two addition and subtraction in JavaScript. The editor thinks it is very practical, so share it with you as a reference and follow the editor to have a look.
Write at the front
This article is from the preliminary solution to the final solution of the idea, the article is long
Although it is an article starting from 0, the thinking leap in the middle may be relatively large.
The parsing of the code is in the train of thought analysis and comments of the article, and there are several key words that the full text will help to understand.
1.Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER
2.15 length string
3.padStart and padEnd
Analysis of the idea of filling holes
I'm sure a lot of people know what's going on.
Console.log (0.1 + 0.2 = 0.3) / / falseconsole.log (0.3-0.2 = 0.1) / / false
If you don't know how to go out and turn right to inquire about it, you won't explain it one by one here!
From the above example, we can see that there is a problem with the addition and subtraction of the decimal point, so what is the solution?
Since there is a problem with the addition and subtraction of the decimal point, let's add and subtract the whole number first. there should be no problem with this. The addition and subtraction of the decimal point can be solved by Baidu itself. It can be calculated through floating point, so there must be no problem with the addition and subtraction of integers. Take a look at the following example
Const MAX = Number.MAX_SAFE_INTEGER;console.log (MAX) / / 9007199254740991console.log (MAX + 2) / / 9007199254740992
What is Number.MAX_SAFE_INTEGER?
Constant represents the largest safe integer in JavaScript
So, Number.MIN_SAFE_INTEGER is the minimum safety factor.
As the name implies, addition and subtraction in JavaScript are stable in these two ranges. Is this safe? There still seems to be a slight problem:
Console.log (10 minutes 21) / / 1e+21console.log (9999999999999999) / 9999999999999999console.log (99999999999999999) / / 10000000000000000console.log (999999999999999999999) / / 1e+21
Judging from the above results, it is not safe.
1. The final result is scientific counting.
two。 I don't know what the specific real data is.
Since there is such a problem in the display of numbers, both the input and output results are represented by strings.
Console.log (`${10 * * 21}`) / / '1e+21'console.log (''+ 10 * * 21) / / '1e+21'console.log ((10 * * 21) .toString ()) / /' 1efu21'
We find that even if it is converted directly to a string, it will still be displayed as a scientific notation, so we can enter the string directly and skip the process of converting to a string.
Solve the pit of integer addition and subtraction
Analyze the possibility first.
1. The input number is within the range of safety factor, and the calculation result is also within the range of safety factor, so the direct output result
two。 Does not meet condition 1 (TODO)
Const MAX = Number.MAX_SAFE_INTEGER; const MIN = Number.MIN_SAFE_INTEGER / * * @ Description: determine whether the input number is within the safety factor of javascript * @ param {number} the number to be checked * @ return {boolean}: return whether the number is a safe integer * / function isSafeNumber (num) {/ / even if num becomes the scientific counting method, it can correctly match MAX, MIN comparison size return MIN = 0 Const str -) {if (arr [I] > 0) {/ / the processing scheme where the result of each part is greater than 0: const str = `$ {arr [I]} `; if (str.length)
< intLen) { // 长度不足 15 的首部补充字符'0' num = str.padStart(intLen, "0") + num; } else if (str.length >IntLen) {/ / throw away the first bit if the length is more than 15, and add a num = str.slice (1) + num; if (I > = 1 & & str [0]! = "0") arr [I-1] + +; else num = "1" + num Direct calculation of} else {/ / length equal to 15 num = str + num;}} else if (arr [I]
< 0) { // 每部分结果小于 0 的处理方案,借位 10的15次方计算,结果恒为正数,首部填充字符'0'到15位 const newV = `${10 ** intLen + Number(arr[i])}`; num = newV.padStart(intLen, "0") + num; if (i >= 1) arr [I-1] -;} else {/ / the result of each part equals 0, with 15 consecutive characters'0' num = "0" .padStart (intLen, "0") + num;}} return num;}
Test results:
For all codes, please click here.
Console.log (MAX) / / 9007199254740991intAdd (MAX,'2') / / '9007199254740993'intAdd (MAX,' 100000000000000000') / '19007199254740991 data 1000000000000000000000intAdd (MAX,' 100000000000000000000000') / '1000009007199254740991'intAdd (MAX, `- ${10 * * 16}`) /'-992800745259009string / there is still a problem, that is, do not use the string in the calculation The following intAdd (MAX, `${10 * * 21}`) / / '10.0000000071992548e+21'intAdd (MAX, `- ${10 * * 21}`) / /' 0' converts scientific calculation
Of course, considering that large numbers are not used in general calculation, writing string addition does feel strange, so you can add judgment to the function, which is the hint of scientific counting and converted to decimal numbers to improve the code:
/ * * @ Description: calculate the sum of two numbers and return the result * @ param {String}: the first integer string added by a * @ param {String}: the first integer string added by b * @ return {string}: return the result * / function intAdd (a = "", b = ") {const statusObj = checkNumber (a, b); if (! statusObj.status) {return statusObj.data } else {let newA, newB, maxLen; const tagA = Number (a)
< 0, tagB = Number(b) < 0; let strA = `${a}`, strB = `${b}`; const reg = /^\-?(\d+)(\.\d+)?e\+(\d+)$/; if (reg.test(a) || reg.test(b)) { console.warn( "由于存在科学计数法,计算结果不一定准确,请转化成字符串后计算" ); strA = strA.replace(reg, function(...rest) { const str = rest[2] ? rest[1] + rest[2].slice(1) : rest[1]; return str.padEnd(Number(rest[3]) + 1, "0"); }); strB = strB.replace(reg, function(...rest) { const str = rest[2] ? rest[1] + rest[2].slice(1) : rest[1]; return str.padEnd(Number(rest[3]) + 1, "0"); }); maxLen = Math.max(a.length, b.length); } else { const lenA = tagA ? strA.length - 1 : strA.length; const lenB = tagB ? strB.length - 1 : strB.length; maxLen = Math.max(lenA, lenB); } const padLen = Math.ceil(maxLen / intLen) * intLen; // 即为会用到的整个数组长度 newA = tagA ? `-${strA.slice(1).padStart(padLen, "0")}` : strA.padStart(padLen, "0"); newB = tagB ? `-${strB.slice(1).padStart(padLen, "0")}` : strB.padStart(padLen, "0"); let result = intCalc(newA, newB); // 去掉正负数前面无意义的字符 '0' const numberResult = Number(result); if (numberResult >0) {while (result [0] = = "0") {result = result.slice (1);}} else if (numberResult
< 0) { while (result[1] === "0") { result = "-" + result.slice(2); } } else { result = "0"; } console.log(result); return result; }}解决整数减法的坑 加法和减法同理,只需要把第二个参数取反后利用加法运算就可以了,由于之前已经提取了模板,可以直接定义减法函数 /** * @Description: 整数减法函数入口 * @param { String }: a 减法的第一个整数字符串 * @param { String }: b 减法的第一个整数字符串 * @return { string }: 返回计算结果 */function intSub(a = "0", b = "0") { const newA = `${a}`; const newB = Number(b) >0? `- ${b}`: `${b}` .slice (1); const result = intAdd (newA, newB); return result;}
Test result
For all codes, please click here.
IntSub ('9037499254750994,'-9007299251310995') / / 18044798506061989 solve the decimal addition pit
At the beginning of the article, it is said that the addition and subtraction of decimals can be calculated by floating point, but since the addition and subtraction of integers have been completed here, can we use the principle of addition and subtraction of integers to solve the calculation of decimals?
The forward completion function padStart often appears in the integer addition code, because adding the character'0' before the integer has no effect on itself.
The decimal also has this principle, adding'0' to the tail also has no effect on the decimal, and then the completed number is calculated by integer addition and subtraction.
First of all, let's take a look at the implementation of addition calculation of decimals.
/ * * @ Description: entry of decimal addition function * @ param {String}: first integer string added by a * @ param {String}: first integer string added by b * @ return {string}: return calculation result * / function floatAdd (a = "0", b = "0") {const statusObj = checkNumber (a, b); if (! statusObj.status) {return statusObj.data } else {const strA = `$ {a} `.split ("."), strB = `$ {b} `.split ("."); let newA = strA [1], newB = strB [1]; const maxLen = Math.max (newA.length, newB.length); const floatLen = Math.ceil (maxLen / intLen) * intLen; newA = newA.padEnd (floatLen, "0"); newB = newB.padEnd (floatLen, "0") NewA = strA [0] [0] = = "-"? `- ${newA}`: newA; newB = strB [0] [0] = "-"? `- ${newB}`: newB; let result = intCalc (newA, newB); let tag = true, numResult = Number (result); / / remove the meaningless characters'0' if (numResult! = 0) after positive and negative numbers {if (numResult)
< 0) { result = result.slice(1); tag = false; } result = result.length === floatLen ? `0.${result}` : `1.${result.slice(1)}`; result = tag ? result : `-${result}`; let index = result.length - 1; while (result[index] === "0") { result = result.slice(0, -1); index--; } } else { result = "0"; } console.log(result); return result; }} 测试结果 floatAdd('0.9037499254750994', '-0.9007299251310995')// 0.0030200003439999解决小数减法的坑 与整数减法的原理相同,可以直接定义减法函数 /** * @Description: 小数减法函数入口 * @param { String }: a 相减的第一个整数字符串 * @param { String }: b 相减的第一个整数字符串 * @return { string }: 返回计算结果 */function floatSub(a = '0', b = '0') { const newA = `${a}` const newB = Number(b) >0? `- ${b}`: `${b.slice (1)} `const result = floatAdd (newA, newB) return result}
Test result
For all codes, please click here.
FloatSub ('0.90374994254750994,'-0.9007299251310995') / / 1.8044798506061989 solves the general problem of integers plus decimals
In fact, in the actual development process, it is not the addition and subtraction of integers or decimals, so the addition and subtraction between integers and decimals should be considered.
The solution here is still to add 0 forward and 0 later.
After the integers and decimals are added together, the integers are added together.
Finally, the decimal point is inserted according to the length of the previously saved integer.
All that's left is to eliminate the meaningless zero and output the result.
/ * * @ Description: calculate the difference between the two numbers and return the result * @ param {String}: the first integer string subtracted by a * @ param {String}: the first integer string subtracted by b * @ return {string}: return the result * / function allSub (a = "0", b = "0") {const newA = `${a}` Const newB = Number (b) > 0? `- ${b}`: `${b}` .slice (1); const result = allAdd (newA, newB); return result } / * * @ Description: calculate the sum of two numbers and return the result * @ param {String}: the first integer string added by a * @ param {String}: the first integer string added by b * @ return {string}: return the result * / function allAdd (a = "0", b = "0") {const statusObj = checkNumber (a, b); if (! statusObj.status) {return statusObj.data } else {const strA = `$ {a} `.split ("."), strB = `$ {b} `.split ("."); let intAs = strA [0], floatA = strA.length = = 1? "0": strA [1]; let intBs = strB [0], floatB = strB.length = = 1? "0": strB [1] / / there may be pure integers or pure decimals 0.xxxxxxx const tagA = intAs > 0 | |! intAs [0] ='-'| | intAs [0] = '0mm, tagB = intBs > 0 | |! intBs [0] =' -'| intBs [0] = '0binary; const maxIntLen = Math.max (intAs.length, intBs.length); const arrIntLen = Math.ceil (maxIntLen / intLen) * intLen; const maxFloatLen = Math.max (floatA.length, floatB.length) Const arrFloatLen = Math.ceil (maxFloatLen / intLen) * intLen; intAs = tagA? IntAs.padStart (arrIntLen, "0"): intAs.slice (1) .padStart (arrIntLen, "0"); intBs = tagB? IntBs.padStart (arrIntLen, "0"): intBs.slice (1) .padStart (arrIntLen, "0"); let newA = floatA = = "0"? IntAs + "0" .padEnd (arrFloatLen, "0"): intAs + floatA.padEnd (arrFloatLen, "0"); let newB = floatB = = "0"? IntBs + "0" .padEnd (arrFloatLen, "0"): intBs + floatB.padEnd (arrFloatLen, "0"); newA = tagA? NewA: `- ${newA}`; newB = tagB? NewB: `- ${newB}`; let result = intCalc (newA, newB); const numResult = Number (result); if (result.length > arrIntLen) {result = result.slice (0,-arrFloatLen) + "." + result.slice (arrFloatLen) } / / remove the meaningless characters'0' if (numResult! = = 0) {if (numResult > 0) {while (result [0] = "0") {result = result.slice (1) }} else if (numResult < 0) {while (result [1] = "0") {result = "-" + result.slice (2);} result = result.slice (1); tag = false;} let index = result.length-1; while (result [index] = = "0") {result = result.slice (0,-1) Index--;} else {result = "0";} if (result [result.length-1] = ".") {result = result.slice (0,-1);} if (result [0] = ".") {result = "0" + result;} console.log (result); return result;}}
Test result
For all codes, please click here.
AllAdd ("9037499254750994", "0.9007299251310995"); / 9037499254750994.9007299251310995allSub ("9037499254750994", "- 0.9007299251310995"); / / 9037499254750994.9007299251310995allAdd ('9037499254750994.903749925475099994,'-900729925131099595'); / 30200003439999.0030200003439999allSub ('9037499254750994.90374994750994.9037499475099499,' 9007299251310995'); / 30003439900309900309939999')
The computation between Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER can be trusted.
The floating point precision problem of decimal addition and subtraction is transferred to integers.
Extra large numbers are added or subtracted when zoning is calculated (reason is point 1)
Split into 15-length strings of each part (the reason is that the length of Number.MAX_SAFE_INTEGER is 16, no matter how to add or subtract, it satisfies the first point, so you don't need to pay attention to the security of addition and subtraction.)
The question of the scientific counting method is whether the matching is the number of the scientific counting method, and then convert it to the decimal system, and give a warning at the same time, because there is an error in the number of the scientific counting method, the calculation will be inaccurate.
Thank you for reading! This is the end of this article on "sample analysis of any two addition and subtraction in JavaScript". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, you can share it for more people to see!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.