How can I store a very very large number in JavaScript? - javascript

What if I want to store a very very large number and then display it. For example factorial of 200.
How can I do this using JavaScript?
I tried the normal way and the result is null or infinity.
function fact(input) {
if(input == 0) {
return 1;
}
return input * fact(input-1);
}
var result = fact(171);
console.log(result);
I tried in normal way and the result is infinity or null.
It seems JavaScript can generate Factorial up to 170.
Look at this picture. This calculator seems able to do it.

The BigInt numeric type is going to be implemented in the future of JavaScript, the proposal is on Stage 3 on the ECMAScript standardization process and it's being supported by major browsers now.
You can use either the BigInt constructor or the numeric literal by appending an n at the end of the number.
In older environments you can use a polyfill.
function fact(input) {
if(input == 0n) {
return 1n;
}
return input * fact(input-1n);
}
const result = fact(171n);
console.log(String(result));

Try this javascript based BigInteger library. There are many to choose from. But i recommend this one https://github.com/peterolson/BigInteger.js
Example:
var num = bigInt("9187239176928376598273465972639458726934756929837450")
.plus("78634075162394756297465927364597263489756289346592");

Related

Correctly format a whole number to a 2 decimal places output in JS but put 0 in front [duplicate]

I have a script which returns a price for a product. However, the price may or may not include trailing zeros, so sometimes I might have 258.22 and other times I might have 258.2. In the latter case, I need to add the trailing zero. How would I go about doing this?
You can use javascript's toFixed method (source), you don't need jQuery. Example:
var number = 258.2;
var rounded = number.toFixed(2); // rounded = 258.20
Edit: Electric Toolbox link has succumbed to linkrot and blocks the Wayback Machine so there is no working URL for the source.
Javascript has a function - toFixed - that should do what you want ... no JQuery needed.
var n = 258.2;
n.toFixed (2); // returns 258.20
I don't think jQuery itself has any string padding functions (which is what you're looking for). It's trivial to do, though:
function pad(value, width, padchar) {
while (value.length < width) {
value += padchar;
}
return value;
}
Edit The above is great for strings, but for your specific numeric situation, rosscj2533's answer is the better way to go.

How to parseInt or ParseInt embedded data with TypeScript in Qualtrics?

Even when I save an integer to embedded data earlier in the survey flow (in previous blocks on different screens), I am not able in Javascript to get the embedded data value, ensure it is parsed as a number/integer, then use it in a loop. Is this something about TypeScript? I didn't see anything about parseInt or ParseInt in the TypeScript documentation.
For example, suppose I do the following:
// Draw a random number
var x = Math.floor(Math.random() * 5);
// Save it in embedded data
Qualtrics.SurveyEngine.setEmbeddedData("foo", x);
// In a later block on a different screen, get the embedded data as an integer
var x_new = "${e://Field/foo}"; // not an int
var x_new = parseInt("${e://Field/foo}"); // doesn't work
var x_new = ParseInt("${e://Field/foo}"); // doesn't work
// Loop using x_new:
for(i = 0; i < x_new; i++) {
console.log(i)
}
Any idea why this isn't working? Perhaps I just don't know how to parseint().
In "normal" JS runtime system, we have parseInt function, the function gets a string (like number string) as a parameter. In this env, we don't support your syntax - "${e://Field/foo}", because it is not a "number string".
In Qualtrics system environment they have parseInt too, but they support their custom syntax "${e://Field/foo}" to get EmbeddedData.
Make sure that your code is running on Qualtrics system environment.
ParseInt is just turning your string into an integer.
Look at the demo below.
let myVar = "${e://Field/foo}"; // This is a string
console.log(myVar); // This prints a string
console.log(parseInt(myVar)); // This prints "NaN", i.e. Not a Number, because the string isn't a representation of a number.

Javascript function to determine if a value is an integer

I came across a problem where I needed to determine if the field being entered by the user was an integer or float. The answer would then preselect a drop down further along a form. After much digging I found lots of framework code but none that actually did the job properly. The test data I used was;
Blank answer,
Non Numeric (Alpha),
1.0,
10,
1.10,
2.4,
3.0,
0.30,
0.00
A lot of other posts were also tested with the above data and I could not find one that passed ALL of the data correctly.
So I have written the following so that it may be reviewed by your good selves and hopefully it will help someone else out should they come across the same situation.
function isInteger(value)
{
//if(isNaN(value))return Nan;//optional check
//test for decimal point
if(!( /^-?\d+$/.test(String(value))))
{
//decimal point found
//if parseInt changes value it must be a float
if(parseInt(value) / 1 != value)return false;
}
//no decimal point so must be integer
return true;
}
Testing for integer values
ECMAScript 6 standard introduces a Number.isInteger().
This function is not yet supported by all major browsers, but a polyfill is listed on the site:
Number.isInteger = Number.isInteger || function isInteger (value) {
return typeof value === 'number' &&
isFinite(value) &&
Math.floor(value) === value
}
In case of user input (which is a string, not an integer), we can use the Number function to perform a type conversion into a number:
var input = '123' // Imagine this came from user
if (Number.isInteger(Number(input)) {
// User entered a valid integer value
}
Note, however, that the type conversion returns a valid integer-like value even for hexadecimal or octal strings. If this is not desired, you would need to further validate the original string. For detailed information about how the type conversion works, see MDN.
If such strict validation is desired, MDN also provides a good implementation using Regex (see the link for example output):
function filterInt (value) {
if(/^(\-|\+)?([0-9]+|Infinity)$/.test(value))
return Number(value)
return NaN
}
Testing for floating point numbers
isFinite() in combination with Number.isInteger() can help achieve our goal.
In case of user input (which is a string, not a float), we must use the Number function to perform a type conversion into a number:
var input = '123.5'
// Perform type conversion to a number
input = Number(input)
if (Number.isFinite(input) && ! Number.isInteger(input)) {
// A finite number that is not an integer can only be a float
}
Alternatively, a stricter variant of the parseFloat() implementation may be used instead, as listed on MDN (see the link for example output):
function filterFloat (value) {
if(/^(\-|\+)?([0-9]+(\.[0-9]+)?|Infinity)$/
.test(value))
return Number(value)
return NaN
}
Since you've mentioned user inputs, your question is about strings, so Number.isInteger is not an option.
To answer this question correctly we have to define more precisely what "integer" means when applied to strings. Is it
a sequence of digits? (example: ১২৪৫)
or a sequence of arabic digits? (example: 0000001)
or any mathematically valid integer representation? (example: 989238402389402394820394802)
or a mathematically valid integer that can be represented exactly in Javascript (i.e. it's less than MAX_SAFE_INTEGER)?
My guess is that you're looking for 4), here's the code for this case:
function isValidIntegerRepresentation(str) {
return /^-?\d+$/.test(str) && String(Number(str)) === str;
}
test = ['0', '00', '123', '-123', '239482039482309820394820394'];
test.forEach(function(n) {
document.write(n + "=" + isValidIntegerRepresentation(n) + "<br>");
});
This is very similar to what you already have.

Chai unittesting - expect(42).to.be.an('integer')

According to http://chaijs.com/api/bdd/#a, a/an can be used to check for the type of a variable.
.a(type)
#param{ String } type
#param{ String } message _optional_
The a and an assertions are aliases that can be used
either as language chains or to assert a value's type.
However, I'm not able to check for the variable beeing an integer. The given examples, e.g. expect('1337').to.be.a('string'); work for me, but the following does not:
expect(42).to.be.an('integer');
expect(42).to.be.an('Integer');
expect(42).to.be.an('int');
expect(42).to.be.an('Int');
All of them are giving me the following error when running mocha:
Uncaught AssertionError: expected 42 to be an integer
How do I test with chai for a variable beeing an integer?
A bit late, but for people coming from search engines, here is another solution:
var expect = require('chai').expect
expect(foo).to.be.a('number')
expect(foo % 1).to.equal(0)
The number check is required because of things such as true % 1 === 0 or null % 1 === 0.
JavaScript doesn't have a separate integer type.
Everything is a IEE 754 floating point number, which would of type number.
This is also possible (at least whithin node):
expect(42).to.satisfy(Number.isInteger);
Here is a more advanced example:
expect({NUM: 1}).to.have.property('NUM').which.is.a('number').above(0).and.satisfy(Number.isInteger);
I feel your pain, this is what I came up with:
var assert = require('chai').assert;
describe('Something', function() {
it('should be an integer', function() {
var result = iShouldReturnInt();
assert.isNumber(result);
var isInt = result % 1 === 0;
assert(isInt, 'not an integer:' + result);
});
});
Depending on the browser/context you are running in there is also a function hanging off of Number that would be of some use.
var value = 42;
Number.isInteger(value).should.be.true;
It has not been adopted everywhere, but most of the places that matter (Chrome, FFox, Opera, Node)
More Info here
Another [not optimal] solution (why not?!)
const actual = String(val).match(/^\d+$/);
expect(actual).to.be.an('array');
expect(actual).to.have.lengthOf(1);

Is there a way to read binary data in JavaScript?

I would like to inject binary data into an object in JavaScript. Is there a way to do this?
i.e.
var binObj = new BinaryObject('101010100101011');
Something to that effect. Any help would be great.
You can use parseInt:
var bin = parseInt('10101010', 2);
The second argument (the radix) is the base of the input.
There's this binary ajax library that is explained here and there's also another binary parser library that can handle more data types.
You could also look at Google Gears which has a binary Blob object or take a look at making a javascript wrapper for Flash which provides a native ByteArray implementation.
Or... you can sit and wait and hope that all these things become standard :)
On all recent browsers you can do:
xhr.overrideMimeType('text/plain; charset=x-user-defined');
And retrieve a string. To get the binary result you will have to do
data.charCodeAt(pos) & 0xff;
On the nightly builds of Firefox and Chrome you can retrieve the value as an ArrayBuffer
xhr.responseType = "arraybuffer";
The result is then accessible there
xhr.mozResponseArrayBuffer // Firefox
xhr.response // Chrome
Then you can apply a TypedArray (eg: Int32Array) or a DataView on the buffer to read the result.
In order to make this process easier, I made a jQuery Patch to support the binary type and a DataView Wrapper that uses the latest available reading feature of the browser.
JavaScript has very little support for raw binary data. In general, it's best to live within this restriction. However, there's a trick I'm considering trying for a project of mine that involves manipulating huge bitmaps to do set operations in an OLAP database. This won't work in IE.
The basic idea is this: coerce the binary data into a PNG to send it to JavaScript, For example, a bitmap might be a black and white PNG, with black being 100% transparent. Then use Canvas operations to do bitwise data manipulation.
The HTML5 Canvas includes a pixel array type, which allows access to bytes in an image. Canvas also supports compositing operations, such as XOR. Lighten and darken should be able to do AND and OR. These operations are likely to be well optimized in any browser that supports them-- probably using the GPU.
If anyone tries this, please let me know how well it works.
That would be the other way around... pow and squareroot might be calculated by the Math-Class... I don't know if it is the fastest way, but it's as fast as the Windows Calculator in the "Programmer View".
AlertFormatedBin();
function AlertFormatedBin()
{
var vals = decToBinArr(31,8);
var i;
var s = "";
var mod = vals.length % 4;
for(i= 0; i <mod;i++)
{
s+=vals[i];
}
if(i>0)
s+=" ";
var j = i;
for(i;i<vals.length;i++)
{
s+=vals[i];
if(i-j != 0 && (i+1-j)%4 == 0)
{
s+=" ";
}
}
alert(s);
}
function decToBinArr(dec, minSize)
{
var mod = dec%2;
var r = new Array();
if(dec > 1)
{
dec-=mod;
var bd = squareRootRoundedDown(dec);
if(minSize && minSize-1 > bd)
bd = minSize-1;
else
var i;
for(i = bd; i>0;i--)
{
var nxt = pow(2,i);
if(dec >= nxt)
{
r[i] = 1;
dec-=nxt;
}
else
{
r[i] = 0;
}
}
}
r[0]= mod;
r.reverse();
return r;
}
function squareRootRoundedDown(dec)
{
if(dec<2)
return 0;
var x = 2;
var i;
for(i= 1;true;i++)
{
if(x>=dec)
{
i = x == dec ? i : i-1;
break;
}
x= x*2;
}
return i;
}
function pow(b,exp)
{
if(exp == 0)
return 0;
var i = 1;
var r= b;
for(i = 1; i < exp;i++)
r=r*b;
return r;
}
In the near future you will be able to use ArrayBuffers and File API Blobs.
As #Zippy pointed out in a comment, the more recent (late 2016) solutions include:
DataView (Standard)
jDataView (polyfill/extension of DataView)
jBinary (built on jDataView)
Javascript doesn't provide a mechanism to load an object in any form other than simple strings.
Closest you can do is serializing the object to a string, optionally encrypting/compressing it, sending it to the browser, and decrypting/decompressing if necessary, checking for sanity, eval() and pray().
Instead of using eval (which is not quite safe), you can use your own format (alternatively, xml or json for which there are plenty of libs) and parse it yourself.
As a side note, if you want this for obfuscation after the browser gets the usable data (after decrypting/decompressing), it is too easy to circumvent.
Percent encoding can unescape strings into a direct 1<->1 representaion of any binary blob and is also portable across browsers;
unescape("%uFFFF%uFFFF%uFFFF");
Most browser exploit's use this technique for embedding shellcode into HTML pages, it works very well for creating arbitrary binary streams.
jBinary "makes it easy to create, load, parse, modify and save complex binary files and data structures in both browser and Node.js."
I haven't used it, but it's what I found when asking the same question asked here...
Welcome to everyone who found this older post on Google. I figured out a solution that works in Chrome as of 2019, so hopefully this is just some added feature or something most people missed.
You can use a 0b prefix to your number. It won't quite get the binary representation, but you can easily convert it to an integer for storage. For example, you could store the binary number 1010 as such:
var binNum = 0b1010 //Stores as an integer, which would be 10
If you're curious, it also works for hexadecimal with the 0x prefix:
var binNum = 0x1010 //Stores as an integer, which would be 4112

Categories