JavaScript: Solve calculation precision problems /mathjs/bignumber.js/big.js/decimal.js

1. Examples of calculation accuracy phenomena

Example 1. Addition

Example 2. Subtraction 

 

Example 3. Multiplication

Example 3, division

2. Why does JS have calculation accuracy problems?

There is only one type of number in JavaScript, Number. That is to say, there is no integer at the bottom of the JavaScript language. All numbers are stored in the form of 64-bit floating-point numbers in the IEEE-754 standard format, and 1 and 1.0 are the same. Because some decimals are infinite in binary representation. JavaScript discards binary numbers beyond 53 bits, so be careful when comparing and computing decimals.

The IEEE Standard for Binary Floating-Point Arithmetic (IEEE 754) is the most widely used floating-point arithmetic standard since the 1980s and is used by many CPUs and floating-point arithmetic units. This standard defines formats for representing floating-point numbers (including negative zero-0 and denormal numbers), some special values ​​(infinity (Inf) and not-a-number (NaN)), and the "floating-point number operators" for these values. "; it also specifies four rounding rules for numbers and five exceptions (including when and how exceptions occur).

3. Solutions

Project technology stack vue3+vite+ts

3.1. Method 1: expand the multiple at the same time and divide by the same multiple

(x * 10 ^ n + y * 10 ^ n)/ 10 ^ n

0.1 +0.2
// 0.30000000000000004
(0.1 *10 + 0.2 *10) / 10
// 0.3

3.2. Method 2, toFixed retains the number of decimal places, and there are still precision problems

3.3. Method 3, mathjs - npm

pnpm add mathjs

Weekly Download 580197 (20230324) 

method operation use shipping result

add

addition

add(1, 2)

3

subtract

subtraction

subtract(2, 1)

1

multiply

multiplication

multiply(2, 2)

4

divide

division

divide(4, 2)

2

round

rounding

round(4.01)

4

bignumber

Convert to bigNumber type. For calculations with arbitrary precision, math.js supports the BigNumber data type, and bignumber returns a Decimal class, and the precision is still difficult to guarantee

bignumber(4.01)

evaluate

direct expression

evaluate('(4.01 + 3) / 2')

3.505

sqrt

square root calculation

sqrt(4)

2

pow

x to the power of y pow(3,3) 27

chain

chain operation

chain(3).add(4).multiply(2).done()

14

atan2

Returns the arctangent of its argument quotient

atan2(15,30)

0.4636476090008061
log Returns the natural Log value of the given number (i.e. the base of e)

log(9)

2.1972245773362196

pi

PI

console.log('pi:', pi)

3.141592653589793
e Euler's constant and the base of natural logarithms, approximately 2.718

console.log('e:', e)

2.718281828459045

derivative

To be verified

console.log('derivative:',derivative('x^2 + x', 'x'))

matrix

matrix operation

matrix([0, 1, 2,  3, 4])

3.4. Method 4, bignumber.js - npm

Weekly Download 8826960 (20230324) 

pnpm add bignumber.js

const num = new BigNumber(1234567890.0123456789)

const num1 = new BigNumber(123.123)

method operation use operation result

toFormat

format

num.toFormat()

1,234,567,890.0123458 retains seven decimal places, the seventh place is rounded according to the eighth place

toFormat

format

num.toFormat(3)

1,234,567,890.012 to three decimal places

toFormat

format

num.toFormat(13)

1,234,567,890.012 保留十三位小数,实际还是保留了七位小数,第七位依据第八位四舍五入,然后位数用0补足

plus

加法

num1.plus(1.1)

minus

减法

num1.minus(1.1)

times

乘法

num1.times(2)

div

除法

num1.div(2)

mod

取余

num1.mod(2)

x.eq(y)

isEqualTo--是否相等

num.eq(num1)

false

x.gt(y)

isGreaterThan--是否大于

num.gt(num1)

true

x.gte(y)

isGreaterThanOrEqualTo--是否大于等于

num.gte(num1)

true

x.lt(y)

isLessThan--是否小于

num.lt(num1)

false

x.lte(y)

isLessThanOrEqualTo--是否小于等于

num.lte(num1)

false

negated

取非,改变数字的正负号

num.negated()

3.5、方法五,big.js - npm

Weekly Download 21,339,420 (20230324) 

pnpm add @types/big.js

const num = new Big(1234567890.0123456789)

const num1 = new Big(123.123)

方法 运算 使用 运算结果

plus

加法

num1.plus(1.1)

minus

减法

num1.minus(1.1)

times

乘法

num1.times(2)

div

除法

num1.div(2)

mod

取余

num1.mod(2)

x.eq(y)

isEqualTo--是否相等

num.eq(num1)

false

x.gt(y)

isGreaterThan--是否大于

num.gt(num1)

true

x.gte(y)

isGreaterThanOrEqualTo--是否大于等于

num.gte(num1)

true

x.lt(y)

isLessThan--是否小于

num.lt(num1)

false

x.lte(y)

isLessThanOrEqualTo--是否小于等于

num.lte(num1)

false

3.6、方法六,decimal.js - npm

Weekly Download 16,251,713 (20230324) 

pnpm add decimal.js

 const num = new Big(1234567890.0123456789)

const num1 = new Big(123.123)

方法 运算 使用 运算结果

plus

加法

num1.plus(new Decimal(1.1))

minus

减法

num1.minus(new Decimal(1.1))

times

乘法

num1.times(new Decimal(2))

div

除法

num1.div(new Decimal(2))

mod

取余

num1.mod(new Decimal(2))

x.eq(y)

isEqualTo--是否相等

num.eq(num1)

false

x.gt(y)

isGreaterThan--是否大于

num.gt(num1)

true

x.gte(y)

isGreaterThanOrEqualTo--是否大于等于

num.gte(num1)

true

x.lt(y)

isLessThan--是否小于

num.lt(num1)

false

x.lte(y)

isLessThanOrEqualTo--是否小于等于

num.lte(num1)

false

4. Welcome to exchange and correct, follow me, and learn together.

Reference link:

JavaScript Math Reference Manual

Guess you like

Origin blog.csdn.net/snowball_li/article/details/129732368