1

I'm doing an algorithm that checks if a number is prime for college, but I came across a connotation and calculation problem where I need to consider large numbers.

One of them was solved with the support of BigInt(), however in arithmetic calculations from a certain number of decimal places it ends up losing precision and consequently returning false true.

For example, multiplying 2 numbers ending in 1,3,7,9 always results in a number ending in 1,3,7,9, but from 3**34 onwards the calculations start to lose precision.

Is there any efficient way to solve this problem in JavaScript?

console.log(`
  ${3**32}, ${BigInt(3**32)}
  ${3**33}, ${BigInt(3**33)}
  ${3**34}, ${BigInt(3**34)}
  ${3**35}, ${BigInt(3**35)}
  ${3**37}, ${BigInt(3**37)}

  ${3*1597*3237*5549}, ${BigInt(3*1597*3237*5549)}
  ${3*1597*3237*5549*13213}, ${BigInt(3*1597*3237*5549*13213)}
  ${3*1597*3237*5549*13213*4543}, ${BigInt(3*1597*3237*5549*13213*4543)}
`);
  • Well the `bigint` data type is your only hope, if it's not working that means there's something wrong with your code. However, nobody can help you because **you did not post any of your code**. – Pointy Jan 26 '22 at 19:56
  • The only reason they would lose precision is if you convert them to ordinary numbers. – Barmar Jan 26 '22 at 20:02
  • @Pointy The question of the problem is the lack of precision in JavaScript arithmetic calculations. No need to share code on something that can be easily tested in browser terminal –  Jan 26 '22 at 20:06
  • @Barmar no conversion was done, just exponentiation and multiplication. –  Jan 26 '22 at 20:07
  • 1
    If you stayed with BigInt it shouldn't lose precision, so obviously you're doing something that converts it. If it can be tested in the browser console, show the steps to reproduce it. – Barmar Jan 26 '22 at 20:09
  • Your added code is **quite clearly** not using `bigint` math, so your whole question doesn't make any sense. There's a stark difference between `bigint` math and ordinary floating-point math. – Pointy Jan 26 '22 at 20:21
  • @Pointy it doesn't make sense since the arithmetic calculation is done before handing the value to ``BigInt()`` (so it will also return a false true), but I added it as a demonstrative example... –  Jan 26 '22 at 20:29
  • @RafaelLucas right but if you're doing the math with ordinary numbers, you're using ordinary numbers; that means normal 64-bit IEEE754 floats. – Pointy Jan 26 '22 at 22:08
  • If you found the solution, please answer your question. On SO, self-answering is OK, while adding the answer to the question is discouraged. – FZs Jan 26 '22 at 22:20
  • @FZs oh, I didn't know that. Thanks for the comment, I'll fix it. –  Jan 27 '22 at 00:12
  • 1
    @RafaelLucas if you're looking for a "BigDecimal" package in Javascript, you can employ decimal.js found at github.com/MikeMcl/decimal.js . – Trentium Jan 27 '22 at 00:40

2 Answers2

2

BigInt type numbers are recommended for this type of operation. I believed that BigInt() was just a conversion method, but is a numerical unit as well.

calculations must also be done using the same number format, and if a division results in a fraction, it is rounded down.

console.log(`
  ${3n**32n}
  ${3n**33n}
  ${3n**34n}
  ${3n**35n}
  ${3n**37n}

  ${3n*1597n*3237n*5549n}
  ${3n*1597n*3237n*5549n*13213n}
  ${3n*1597n*3237n*5549n*13213n*4543n}

  ${1n/3n}
  ${2n/3n}
`);
1

You could.... not use Javascript

Outside of that, you could take Mike Cowlishaw's ANSI C implementation of arbitrary precision decimal arithmetic decNumber or decFloats package (http://speleotrove.com/decimal/#decNumber) and write Node.js bindings for it.

Mike Cowlishaw knows a thing or 3 about arithmetic:

In 1998 and 1999 he was also Project Editor and technical Chair for the ECMAScript (JavaScript) international standard (now ISO 16262).

From 1999 through 2009, he worked on new decimal arithmetic packages (including IBM’s BigDecimal class for Java and the decNumber C library), invented the Densely Packed Decimal encoding, and helped specify new decimal hardware architecture. He is the author of the General Decimal Arithmetic specifications, and was the Specification Lead for the decimal arithmetic enhancements included in Java 5 in 2004.

Mike championed the addition of the new decimal types and arithmetic to the IEEE 754 Standard for Floating-Point Arithmetic and to the C, C++, COBOL, and other languages (as well as in hardware), and remains active in the related work of a number of standards organizations, including ECMA, ISO, ANSI, IEEE, BSI, and W3C. He has been the Editor of the IEEE 754 standard since its first ballot in 2007 and through its publication in 2008 and as ISO/IEC/IEEE 60559 in 2011, and was a member of the Program Committee for the IEEE Symposium on Computer Arithmetic. IEEE 754 was further enhanced, with Mike as Editor, and the revised standard was published in 2019.

Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135
  • is that the study involves JavaScript kk I would just like to know how far it is possible to do calculations of this level in a slightly higher level language. –  Jan 26 '22 at 20:18