Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Large numbers - Math in JavaScript

I'm developing a 3D space game, which is using alot of math formulas, navigation, ease effects, rotations, huge distances between planets, objects mass, and so on...

My Question is what would be the best way in doing so using math. Should I calculate everything as integers and obtain really large integers(over 20 digits), or use small numbers with decimals.

In my experience, math when using digits with decimals is not accurate, causing strange behavior when using large numbers with decimals.

like image 896
Rotar Paul Avatar asked Jun 16 '16 21:06

Rotar Paul


People also ask

How do you handle large numbers in JavaScript?

To represent integers larger than 2 to the 53rd power minus 1 in JavaScript, we can use the BigInt object to represent the values. It can be manipulated via normal operations like arithmetic operators — addition, subtraction, multiplication, division, remainder, and exponentiation.

What is the largest possible number in JavaScript?

JavaScript Number MAX_VALUE MAX_VALUE returns the largest number possible in JavaScript. Number. MAX_VALUE has the value of 1.7976931348623157e+308.

What is a BigInt in JavaScript?

BigInt is a special numeric type that provides support for integers of arbitrary length. A bigint is created by appending n to the end of an integer literal or by calling the function BigInt that creates bigints from strings, numbers etc.

What is Bignumber in JavaScript?

A BigInt value, also sometimes just called a BigInt, is a bigint primitive, created by appending n to the end of an integer literal, or by calling the BigInt() function (without the new operator) and giving it an integer value or string value.


2 Answers

I would avoid using decimals. They have known issues with precision: http://floating-point-gui.de/


I would recommend using integers, though if you need to work with very large integers I would suggest using a big number or big integer library such as one of these:

  • http://jsfromhell.com/classes/bignumber
  • https://silentmatt.com/biginteger/

The downside is you have to use these number objects and their methods rather than the primitive Number type and standard JS operators, but you'll have a lot more flexibility with operating on large numbers.

Edit:
As le_m pointed out, another downside is speed. The library methods won't run as fast as the native operators. You'll have to test for yourself to see if the performance is acceptable.

like image 95
skyline3000 Avatar answered Sep 30 '22 04:09

skyline3000


Use the JavaScript Number Object

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number

Number.MAX_SAFE_INTEGER The maximum safe integer in JavaScript (2^53 - 1).

Number.MIN_SAFE_INTEGER The minimum safe integer in JavaScript (-(253 - 1)).

var biggestInt = 9007199254740992;
var smallestInt = -9007199254740992;

var biggestNum = Number.MAX_VALUE;
var smallestNum = Number.MIN_VALUE;
var infiniteNum = Number.POSITIVE_INFINITY;
var negInfiniteNum = Number.NEGATIVE_INFINITY;
var notANum = Number.NaN;

console.log(biggestInt); // http://www.miniwebtool.com/scientific-notation-to-decimal-converter/?a=1.79769313&b=308
console.log(smallestInt); // http://www.miniwebtool.com/scientific-notation-to-decimal-converter/?a=5&b=-32

console.log(biggestNum);
console.log(smallestNum);
console.log(infiniteNum);
console.log(negInfiniteNum);
console.log(notANum);

debugger;

I can only imagine that this is a sign of a bigger problem with your application complicating something that could be very simple.


Please read numerical literals

http://www.ecma-international.org/ecma-262/5.1/#sec-7.8.3

Once the exact MV for a numeric literal has been determined, it is then rounded to a value of the Number type. If the MV is 0, then the rounded value is +0; otherwise, the rounded value must be the Number value for the MV (as specified in 8.5), unless the literal is a DecimalLiteral and the literal has more than 20 significant digits, in which case the Number value may be either the Number value for the MV of a literal produced by replacing each significant digit after the 20th with a 0 digit or the Number value for the MV of a literal produced by replacing each significant digit after the 20th with a 0 digit and then incrementing the literal at the 20th significant digit position. A digit is significant if it is not part of an ExponentPart and

  • it is not 0;
  • or there is a nonzero digit to its left and there is a nonzero digit, not in the ExponentPart, to its right.

Clarification

I should add that the Number Object wrapper supposedly offers precision to 100 (Going above this number will give you a RangeType error) significant digits in some browsers, however most environments currently only implement the precision to the required 21 significant digits.

Reading through OPs original question, I believe skyline provided the best answer by recommending a library which offers well over 100 significant digits (some of the tests that I got to pass were using 250 significant digits). In reality, it would be interesting to see someone revive one of those projects again.

like image 30
Joseph Casey Avatar answered Sep 30 '22 06:09

Joseph Casey