/** * Floatobj contains subtraction four methods to ensure that floating-point arithmetic does not lose precision * * We know that there is a loss of precision (or rounding error) in the calculation of floating-point numbers in a computer programming language, the root cause is that the binary and implementation bits limit some number cannot be limited representation * The following are binary representations of decimal decimals * 0.1 >> 0.0001 1001 1001 1001 ... (1001 Infinite Loop) * 0.2 >> 0.0011 0011 0011 0011 ... (0011 infinite loops) * The storage of each data type in the computer is a finite width, such as JavaScript uses 64-bit to store the number type, so the excess will go away. The part of the shed is the missing part of the precision. * * * * * * * * * * * * * * * * * * * * * * * * * * 0.1 + 0.2 = 0.30000000000000004 (0.00000000 000004) * 0.2 + 0.4 = = 0.6000000000000001 (more than 0.0000000000001) * 19.9 * 100 = 1989.9999999999998 (less than 0.0000000000002) * * Floatobj.add (0.1, 0.2) >> 0.3 * floatobj.multiply (19.9, +) >> 1990 **/varFloatobj =function() { /** Determine if obj is an integer*/ functionIsinteger (obj) {returnMath.floor (obj) = = =obj; } /** Converts a floating-point number to an integer, returning an integer and a multiple. such as 3.14 >> 314, multiples of * @param floatnum {number} decimal * @return {Object} * {times:100, num:314} */ functionTointeger (floatnum) {varret = {times:1, num:0}; if(Isinteger (floatnum)) {Ret.num=Floatnum; returnret; } varStrfi = Floatnum + "; varDotpos = Strfi.indexof ('. ')); varLen = Strfi.substr (dotpos+1). length; varTimes = Math.pow (10, Len); //var intnum = parseint (Floatnum * times + 0.5, 10);//test negative numbers are lost in precision varIntnum = parseint (Floatnum * times, 10); Ret.times=Times ; Ret.num=Intnum; returnret; } /** Core method, realize subtraction operation, ensure no loss of precision * idea: Enlarge decimal to Integer (multiply), perform arithmetic operation, and then reduce to decimal (except) * * @param a {number} operand 1 * @param b { Number} operand 2 * @param op {string} operation type with subtraction (add/subtract/multiply/divide) **/ functionoperation (A, B, op) {varO1 =Tointeger (a); varO2 =Tointeger (b); varN1 =O1.num; varN2 =O2.num; varT1 =O1.times; vart2 =O2.times; varmax = t1 > t2?t1:t2; varresult =NULL; Switch(OP) { Case' Add ': if(T1 = = = T2) {//two decimal digits of the sameresult = N1 +N2; } Else if(T1 > T2) {//O1 decimal Place greater than O2result = N1 + N2 * (T1/T2); } Else{//O1 decimal Place less than O2result = N1 * (T2/T1) +N2; } returnResult/Max; Case' Subtract ': if(T1 = = =T2) {Result= N1-N2; } Else if(T1 >T2) {Result= n1-n2 * (T1/T2); } Else{result= N1 * (T2/T1)-N2; } returnResult/Max; Case' Multiply ': Result= (N1 * n2)/(T1 *T2); returnresult Case' Divide ': Result= (n1/n2) * (T2/t1); returnresult; } } //four interfaces of the subtraction functionAdd (A, b) {returnOperation (A, B, ' add '); } functionSubtract (A, b) {returnOperation (A, B, ' subtract '); } functionMultiply (A, b) {returnOperation (A, B, ' multiply '); } functionDivide (A, b) {returnOperation (A, B, ' divide '); } //if it is an integer, the decimal point is not preserved and only the decimal point exceeds the specified number of digits. functiontoFixed (num, digits) {varTimes = Math.pow (10, digits); vardes = num *Times ; returnparseint (DES, 10)/Times ; } //exports return{add:add, subtract:subtract, multiply:multiply, Divide:divide, Tofixed:tofix Ed}} ();
Another option is to refer to:
Https://github.com/MikeMcl/big.js
Calculation accuracy of JS float floating point number