How to implement Big Int in Javascript? - javascript

I am working on open-source project. It doesn’t properly meet its specs due to the representation as JavaScript numbers ie let,const... I want to add support for Int, Long Int, and Big Ints similar to c++.
Can anyone please suggest any resource or approach to achieve this?
Thank you

JavaScript has gained BigInt support as a feature a couple of years ago. By now, most users have browsers new enough to support it: https://caniuse.com/bigint.
If you want to support even older browsers, there are a variety of pure JavaScript implementations with different pros and cons, for example JSBI, MikeMcl's bignumber.js, Peter Olson's BigInteger.js, Yaffle's BigInteger. You can study their sources to learn how they're implemented.
For learning about how native BigInt is implemented, this V8 blog post gives some insight.
Side note: JavaScript is perfectly capable of expressing 32-bit integers à la C++ int/int32_t, no BigInts or libraries are required for that. Bitwise binary operations cause JavaScript numbers to behave like 32-bit integers, so you can write (a + b) | 0 to make the addition behave like a C++ int addition.
If all you need is 64-bit integers, it's not difficult to represent them as pairs of 32-bit numbers. There are also several existing libraries that do that (just use your favorite search engine). If you don't actually need arbitrarily big integers, that may be a nice alternative.

Related

Why is this false? Math.ceil(5.0000000000000009) === Math.ceil(5.00000000000000009) // false [duplicate]

This question already has an answer here:
What is the standard solution in JavaScript for handling big numbers (BigNum)?
(1 answer)
Closed 8 years ago.
I'm looking for a Mathematical solution that deals with really (long, big, huge, storms) numbers. I haven't found anything yet, But I don't wanna think that this problem hasn't be solve at this time. I'm looking for an easy Number solution, like Microsoft Excel Precision (30 decimals), or a BigInteger (Java) solution. in Javascript of course.
While looking for an big integer library for an ElGamal crypto implementation I tested several libraries with the following results:
I recommend this one: Tom Wu's jsbn.js (http://www-cs-students.stanford.edu/~tjw/jsbn/)
Comprehensive set of functions and fast
Leemon Baird's big integer library (http://www.leemon.com/crypto/BigInt.js)
Comprehensive set of functions and pretty fast
BUT: Negative number representation is buggy!
bignumber.js (https://github.com/MikeMcl/bignumber.js)
Pretty complete set of functions
BUT: Converting really big numbers from strings into BigNumber objects result in INFINITY
Scheme arithmetic library for JavaScript (https://github.com/jtobey/javascript-bignum)
JS-Implementation of Scheme arithmetic functions
BUT: No function for y= x^e mod n
I haven't tested this by myself: BigNumber (http://jsfromhell.com/classes/bignumber)
Functions for high precision claculations
BUT: It's said to be slow due to internal representation of numbers as strings
There's a BigInteger library for JavaScript available here:
jsbn.js
(Note that I haven't used this myself. Try it and see what you think.)
There is also Silent Matt's library for Big Integers. It does not handle decimals.

JavaScript numbers, all the same size in memory?

I'm reading the Number Type section of the book Professional JavaScript for Web Developers. It seems to say that all ECMAScript numbers are binary64 floating point, which is corroborated by this MDN article. But the book author also says:
Because storing floating-point values uses twice as much memory as storing integer values, ECMAScript always looks for ways to convert values into integers.
I expected numbers to each occupy the same amount of memory: 64 bits. And the MDN article says, "There is no specific type for integers". Anyone know what the book author meant? How can integers take up less memory when they're stored as 64-bit floats (if I have that right)? You'll find the whole section at the link above (free sample of the book).
JavaScript doesn't have any other number type than double precision floating point (except in ECMAScript 6 typed arrays), but the underlying implementation may choose to store the numbers in any way it likes as long as the JavaScript code behaves the same.
JavaScript is compiled nowadays, which means that it can be optimised in many ways that are not obvious in the language.
If a local variable in a function only ever takes on an integer value and isn't exposed outside the function in any way, then it could actually be implemented using an integer type when the code is compiled.
The implementation varies in different browsers. Currently it seems to make a huge difference in MS Edge, a big difference in Firefox, and no difference at all in Chrome: http://jsperf.com/int-vs-double-implementation (Note: jsperf thinks that MS Edge is Chrome 42.)
Further research:
The JS engines Spidermonkey (Firefox), V8 (Chrome, Opera), JavaScriptCore (Safari), Chakra (IE) and Rhino (and possibly others, but those are harder to find implementation details about) use different ways of using integer types or storing numbers as integers when possible. Some quotes:
"To have an efficient representation of numbers and JavaScript
objects, V8 represents both of us with a 32 bits value. It uses a bit
to know if it is an object (flag = 1) or an integer (flag = 0) called
here SMall Integer or SMI because of its 31 bits."
http://thibaultlaurens.github.io/javascript/2013/04/29/how-the-v8-engine-works/
"JavaScript does not have a built-in notion of an integer value, but
for efficiency JavaScriptCore will represent most integers as int32
rather than as double."
http://trac.webkit.org/wiki/JavaScriptCore
"[...] non-double values are a 32-bit type tag and a 32-bit payload,
which is normally either a pointer or a signed 32-bit integer."
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals
"In Windows 10 and Microsoft Edge, we’ve started optimizing Chakra’s
parser and the JIT compiler to identify non const variable
declarations of integers that are defined globally and are never
changed during the course of the execution time of the program."
https://blogs.windows.com/msedgedev/2015/05/20/delivering-fast-javascript-performance-in-microsoft-edge/
Because storing floating-point values uses twice as much memory as storing integer values, ECMAScript always looks for ways to convert values into integers.
This paragraph is complete nonsense. Ignore it!
Numbers are numbers. ECMAScript makes no distinction whatsoever between floating-point and integer numeric values.
Even within most JS runtimes, all numeric values are stored as double-precision floating point.
Not sure I fully understood your question, but "There is no specific type for integers" means that JavaScript doesn't recognize separate types for integers and floats, but they are both typed as Numbers. The int/float separation happens "behind the curtains", and that's what they meant by "ECMAScript always looks for ways to convert values into integers".
The bottom line is that you don't have to worry about it, unless you specifically need your variables to mimic integers or floats for use in other languages, in which case it's probably (did I say probably?) the best to pass them as strings (because you'd have trouble passing, say, 5.0 as a float because JS would immediatelly convert it to 5, exactly because of the "ECMAScript always looks for ways to convert values into integers" part).
alert(5.0); // don't expect a float from this

Javascript calculate with number over Number.MAX_VALUE [duplicate]

This question already has an answer here:
What is the standard solution in JavaScript for handling big numbers (BigNum)?
(1 answer)
Closed 8 years ago.
I'm looking for a Mathematical solution that deals with really (long, big, huge, storms) numbers. I haven't found anything yet, But I don't wanna think that this problem hasn't be solve at this time. I'm looking for an easy Number solution, like Microsoft Excel Precision (30 decimals), or a BigInteger (Java) solution. in Javascript of course.
While looking for an big integer library for an ElGamal crypto implementation I tested several libraries with the following results:
I recommend this one: Tom Wu's jsbn.js (http://www-cs-students.stanford.edu/~tjw/jsbn/)
Comprehensive set of functions and fast
Leemon Baird's big integer library (http://www.leemon.com/crypto/BigInt.js)
Comprehensive set of functions and pretty fast
BUT: Negative number representation is buggy!
bignumber.js (https://github.com/MikeMcl/bignumber.js)
Pretty complete set of functions
BUT: Converting really big numbers from strings into BigNumber objects result in INFINITY
Scheme arithmetic library for JavaScript (https://github.com/jtobey/javascript-bignum)
JS-Implementation of Scheme arithmetic functions
BUT: No function for y= x^e mod n
I haven't tested this by myself: BigNumber (http://jsfromhell.com/classes/bignumber)
Functions for high precision claculations
BUT: It's said to be slow due to internal representation of numbers as strings
There's a BigInteger library for JavaScript available here:
jsbn.js
(Note that I haven't used this myself. Try it and see what you think.)
There is also Silent Matt's library for Big Integers. It does not handle decimals.

JavaScript and Dealing with Floating Point Determinism

I'm looking to build a browser multiplayer game using rollback netcode that runs a deterministic simulation on the clients. I prototyped the netcode in Flash already before I ran into the floating point roadblock.
Basically, from what I understand, integer math in Flash is done by casting ints to Numbers, doing the math, then casting back to int. It's faster apparently, but it means that there's no chance of deterministic math across different computer architectures.
Before I dump all my eggs into the JavaScript basket then, I'd like to ask a few questions.
Is there true integer arithmetic on all major browsers in JavaScript? Or do some browsers do the Flash thing and cast to floats/doubles to do the math before casting back to int?
Does something like BigDecimal or BigNum work for deterministic math across different computer architectures? I don't mind some performance loss as long as it's within reason. If not, is there some JavaScript fixed point library out there that solves my problem?
This is a long shot, but is there a HTML5 2D game engine that has deterministic math for stuff like x/y positions and collisions? The list of game engines is overwhelming to say the least. I'm uneasy about building a deterministic cross browser compatible engine from scratch, but that might be what I have to do.
NOTE: Edited from HTML5 to JS as per responses. Apologies for my lack of knowledge.
This is a Javascript issue - not an HTML5 one.
All Javascript math is done using IEEE754 floating point double values - there are no "ints".
Although IEEE754 requires (AFAIK) a specific answer for each operation for any given input, you should be aware that JS interpreters are potentially free to optimise expressions, loops, etc, such that the floating point operations don't actually execute in the order you expect.
Over the course of a program this may result in different answers being produced on different browsers.

Performance of bitwise operators in javascript

One of the main ideas behind using bitwise operators in languages like C++/java/C# is that they're extremely fast. But I've heard that in javascript they're very slow (admittedly a few milliseconds probably doesn't matter much today). Why is this so?
(this question discusses when bitwise operators are used, so I'm changing the focus of this question to performance.)
This is quite an old question, but no one seemed to answer the updated version.
The performance hit that you get with JavaScript that doesn't exist in C/C++ is the cast from floating point representation (how JavaScript strores all of its numbers) to a 32 bit integer to perform the bit manipulation and back.
Nobody uses hex anymore?
function hextoRgb(c) {
c = '0x' + c.substring(1);
return [(c >> 16) & 255, (c >> 8) & 255, c & 255];
}
var c1 = hextoRgb('#191970');
alert('rgb(' + c1.join(',') + ')');
I use bitwise shift of zero in JS to perform quick integer truncation:
var i=3.141532;
var iTrunc=i>>0; //3
When would you want to use them? You would want to use them when you want to do bitwise operations. Just like you'd use boolean operators to do boolean operations, and mathematical operators to do mathematical operations.
If you are comfortable with bitwise operators it is very natural to use them for some applications. They can be used for many purposes other than an over-optimized boolean array. Of course, these circumstances don't come up very often in Javascript programming, but that's no reason why the operators shouldn't be available.
I found some good info #
http://dreaminginjavascript.wordpress.com/2009/02/09/bitwise-byte-foolish/
Apparently they perform very well these days. Why would you use them? Same reason you would anywhere else.
I'd think it's up to the implementer to make an operator efficient or inefficient. For example, there's nothing that prevents a JavaScript implementer from making a JITting VM, which turns a bitwise op into 1 machine instruction. So there's nothing inherently slow about "the bitwise operators in JavaScript".
There is an NES emulator written in JavaScript - it seems to make plenty of use of bitwise operations.
I am doubtful that bitwise operation are particularly slow in javascript. Since such operations can map directly to CPU operations, which are themselves quite efficient, there doesn't appear to be any inherent characteristic of bitwise operations that would force them to be irremediably slow in javascript.
Edit December 2015: I stand corrected! The performance hit that Javascript suffers in regards to bitwise operations comes from the need of converting from float to int and back (as all numeric variables in Javascript are stored as floating point values). Thank you to Chad Schouggins for pointing that out.
Never the less, as indicated in several responses, there exist various applications of javascript which rely on bitwise operation (ex: crytography and graphics) and which are not particularly slow... (see silky and Snarfblam on this page). This suggests that while slower than C/C++ and other languages which translate directly bitwise ops to single native CPU instructions, bitwise operations are all that sluggish.
Let's never the less entertain the possibility that some particular reasons caused the various implementers of javascript hosts to implement bitwise ops in a fashion that makes these extremely slow, and see if this even matters...
Although javascript has been used for other purposes, the most common use of this language in in providing user interface type of services.
BTW, I do not mean this in any pejorative way at all; performing these smart UI functions, and considering various constraints imposed on the language and also the loose adherence to standards, has required -and keeps requiring- talented javascript hackers.
The point is that in the context of UI-type requirements, the need for any quantity of bitwise operations susceptible of exposing the slowness of javascript in handling such operations is uncommon at best. Consequently, for typical uses, programmers should use bitwise operations where and if this approach seems to flow well with overall program/data and they should do so with little concern for performance issues. In the unlikely case of performance bottleneck arising from bitwise use, one can always refactor things, but one is better off staying clear from early optimization.
The notable exception to the above is with the introduction of canvas, on modern browsers, we can expect that more primitive graphic functions will be required of javascript hosts, and such operations can require in some cases heavy doses of bitwise operations (as well as healthy does of math functions). It is likely that these services will eventually be supported by way of javascript libraries (and even end-up as languages additions). For such libraries the common smarts of the industry will have been put to use to figure out the most efficient approaches. Furthermore and if indeed there is a weakness in javascript performance with bitwise ops, we'll get some help, for I predict that the javascript implementations on various hosts (browsers) will be modified to improve this particular area. (This would follow the typical pattern of evolution of javascript, that we've seen over the years.)
When speed is paramount, you can use them for bit-masking: http://snook.ca/archives/javascript/storing_values/
Also, if you need to support Netscape 4, you'd use them to deal with Document.captureEvents(). Not that any respectable company would have you write JS for NS4...
People do interesting things in JavaScript.
For example there are a lot of cryptography algorithms implemented in it (for various reasons); so of course bitwise operators are used.
Using JavaScript in its Windows Scripting Host JScript incarnation, you might have cause to use bitwise operators to pick out flags in values returned from WMI or Active Directory calls. For example, the User Access value of a user's record in AD contains several flags packed into one long integer.
ADS_UF_ACCOUNTDISABLE = 0x00000002;
if (uac & ADS_UF_ACCOUNTDISABLE == ADS_UF_ACCOUNTDISABLE) {
// user account has been disabled
}
Or someone's arbitrary table structure may contain such a field, accessible through ADO with JScript.
Or you may want to convert some retrieved data into a binary representation on any platform, just because:
BinaryData = "L";
BinaryString = BinToStr(BinaryData, ".", "x");
// BinaryString => '.x..xx..'
So there are numerous reasons why one might want to do bit manipulation in JavaScript. As for performance, the only way to know is to write it and test it. I suspect in most cases it would be perfectly acceptable, not significantly worse than any other of the multitude of inefficiencies these systems contain.
A lot of bitwise operations are being benchmarked here: http://jsperf.com/rounding-numbers-down/3
However, feel free to create your own performance testcase on jsPerf!

Categories

Resources