Issue with combining large array of numbers into one single number - javascript

I am trying to convert an array of numbers into one single number, for example
[1,2,3] to 123.
However, my code can't handle big arrays since it can’t return exact number. Such as
[6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,5,4,3] returns 6145390195186705000
Is there any way that I could properly convert into a single number.I would really appreciate any help.
var integer = 0;
var digits = [1,2,3,4]
//combine array of digits into int
digits.forEach((num,index,self) => {
integer += num * Math.pow(10,self.length-index-1)
});

The biggest integer value javacript can hold is +/- 9007199254740991. Note that the bitwise operators and shift operators operate on 32-bit ints, so in that case, the max safe integer is 2^31-1, or 2147483647.
In my opinion, you can choose one of the following:
store the numbers as strings and manipulate them as numbers; you might have to implement special functions to add/subtract/multiply/divide them (these are classic algorithmic problems)
use the BigInt; BigInts are a new numeric primitive in JavaScript that can represent integers with arbitrary precision. With BigInts, you can safely store and operate on large integers even beyond the safe integer limit. Unfortunately, they work only with Chrome right now. If you want to work with other browsers, you might check this or even this if you work with angularjs or nodejs.
Try the following code in the Chrome's console:
let x = BigInt([6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,5,4,3].join(''));
console.log(x);
This will print 6145390195186705543n. The n suffix marks that it is a big integer.
Cheers!

You can use JavaScript Array join() Method and parse it into integer.
Example:
parseInt([6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5].join(''))
results:
6145390195186705
Edited: Use BigInt instead of parseInt , but it works only on chrome browser.

The largest number possible in Javascript is
+/- 9007199254740991
Use BigInt. Join all numbers as a string and pass it in BigInt global function to convert it into int
var integer = 0;
var digits = [1,2,3,4]
//combine array of digits into int
digits.forEach((num,index,self) => {
integer += num;
});
integer= BigInt(integer);
Note : Works only on Chrome as of now. You can use othee libraries like BigInteger.js or MathJS

Related

Assigning BigInt stores wrong number (number+1)

I want to define a BigInt number in JavaScript. But when I assign it, the wrong number is stored. In fact 1 is added to the number when storing.
let num = BigInt(0b0000111111111111111111111111111111111111111111111111111111111111)
console.log(num) // Output: 1152921504606846976n
console.log(num.toString(2)) // Output: 1000000000000000000000000000000000000000000000000000000000000
So the number stored is 1152921504606846976, but it should be 11529215046068469765. Why is that?
Converting a Number to a BigInt can't create bits that weren't there before.
0b1 (just like 1) is a Number literal, so it creates a Number.
0b1n (just like 1n) is a BigInt literal, so it creates a BigInt.
By writing BigInt(0b1), you're first creating a Number and then converting that to a BigInt. As long as the value is 1, that works just fine; once the value exceeds what you can losslessly store in a Number [1], you'll see that the value of the final BigInt won't match the literal you wrote down. Whether you use binary (0b...), decimal, or hex (0x...) literals doesn't change any of that.
(And just to be extra clear: there's no reason to write BigInt(123n), just like you wouldn't write Number(123). 123n already is a BigInt, so there's nothing to convert.)
A simple non-BigInt way to illustrate what's happening is to enter 12345678901234567890 into your favorite browser's DevTools console: you can specify Number literals of any length you want, but they'll be parsed into an IEEE754 64-bit "double", which has limited precision. Any extra digits in the literal simply can't be stored, though of course each digit's presence affects the magnitude of the number.
[1] Side note: this condition is more subtle than just saying that Number.MAX_SAFE_INTEGER is the threshold, though that constant is related to the situation: any integral number below MAX_SAFE_INTEGER can be stored losslessly, but there are plenty of numbers above MAX_SAFE_INTEGER that can also be represented exactly. Random example: 1e20.

How can i get the same number value as given in JavaScript?

I got a number 1267508826984464384 from json response. Here i print the number.
<script>
var num = 1267508826984464384;
console.log(num);
var num = "1267508826984464384";
console.log(num);
</script>
output is
In the first print the output is different from the original value. I need the same value as given.
Is it possible?
JavaScript uses floating point under the hood to store numbers. Floating point double precision, which is what JavaScript uses, can only store 64 bits of data. With the way numbers are represented in this manner, this means that there's a limit to how big a Number can normally be (2^53 - 1 for double precision floating point). Your number in the example has gone over this limit (overflow) and hence is being rounded by JavaScript.
You can use BigInt:
var num = BigInt(1267508826984464384);
console.log(num); // logs 1267508826984464384n, with n representing that it's a BigInt type
var num = "1267508826984464384";
console.log(num); // logs 1267508826984464384
May be helpful to read What Every Programmer Should Know About Floating-Point Arithmetic for more information on why this is the case.
They are different types (int and string, respectfully). What you are seeing in the top example is integer overflow (safely abstracted by JS). You can use a big integer to bypass this issue
const hugeString = BigInt("1267508826984464384")
console.log(hugeString + 1n) // 1267508826984464385n
The type of this is BitInt and it will safely allow you to represent your number as a integer. This type must be treated different and the additions must also be BigInt (as shown in the example above).
BigInt is a built-in object that provides a way to represent whole numbers larger than 253 - 1, which is the largest number JavaScript can reliably represent with the Number primitive and represented by the Number.MAX_SAFE_INTEGER constant. BigInt can be used for arbitrarily large integers.
From MDN. You can use it like so:
const theBiggestInt = 9007199254740991n
const alsoHuge = BigInt(9007199254740991)
// ↪ 9007199254740991n
const hugeString = BigInt("9007199254740991")
// ↪ 9007199254740991n
const hugeHex = BigInt("0x1fffffffffffff")
// ↪ 9007199254740991n
const hugeBin = BigInt("0b11111111111111111111111111111111111111111111111111111")
// ↪ 9007199254740991n
RegEx for finding numbers and quoting them. Looks for prop value boundaries and a sequence of digits and optionally one period, and replaces inserting with quotes around the number value.
RegEx should be adjusted for maximum length or tolerances for numbers to be quoted as strings.
key or value prefix/suffix can be added, so that a JSON.parse reviver function can recognize them and parse to big.js or BigInt.
In most cases, you probably already know if you might receive a large number, and could probably just use a trivial RegEx replace on the specific property you need.
And, you should be coordinating with the server-side to give the data to you in another form that is safe to consume.
Parsing number strings using BigInt and big.js.
str = String.raw `{"j\"son":1234561251261262131231231231231231231231231232123123123,
"array":
[123123123124124214124124124124.111,
124124124124124124124124124,
124124124124124124124124
]}
`
str = str.replace(/((?:{|,|\[)\s*(?:"(?:[^"]|\\")+"\s*:\s*)?)(\d+\.?\d*)(\s*)(?=,|}|\])/g, `$1"$2"$3`)
// note: capture group $3 is just whitespace, which can normally be ignored; included to be "technically accurate"
console.log(
str,
(BigInt(JSON.parse(str)[`j"son`]) + 1n).toString(),
(Big(JSON.parse(str).array[0]).plus(0.0003)).toFixed()
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/big.js/5.2.2/big.min.js" integrity="sha256-gPNmhPlEOUlyAZomtrYRW/HSIjBOOl2LVxft3rsJpxI=" crossorigin="anonymous"></script>

How to get digits from a BigInt in javascript?

I am working on problem n°104 of project Euler Problem 104 and would like to do it in javascript.
In order to solve this problem I need to compute large values of the Fibonacci sequence, but the numbers produced by this sequence are too large to be handle by classic Number, so I'm using BigInt supported in the latest versions of javascript.
Once I've got a particular result stored in a BigInt, I need to check it's 10 first, and last digits.
To get the digits from a Number we usually do something like in the code below, but when the number becomes very large, things go wrong:
let number = BigInt(123456789)
console.log(number.toString())
console.log(number.toString()[3]) // Result is fine
let bigNumber = BigInt(1234567891111111111111111111111111111)
console.log(bigNumber.toString())
console.log(bigNumber.toString()[30]) // unpredictable result
It seems like the "toString()" methods is only using the precision of the Number type (2^53 I believe), thus we are quickly losing precision on the last digits of the BigInt number. The problem is I can't find other methods to extract those digits.
Edit :
I need the precision to be perfect because basicaly what i'm doing for example is :
Compute Fibonacci(500) = 280571172992510140037611932413038677189525
Get the 10 last digits of this number : 8677189525 (this is where is lose the precision)
And then to solve my problem I need to check that those 10 last digits contains all the digits from 1 to 9
For big numbers, I think you should add the n suffix:
let number = BigInt(123456789)
console.log(number.toString())
console.log(number.toString()[3]) // Result is fine
let bigNumber = 1234567891111111111111111111111111111n // <-- n suffix, literal syntax
console.log(bigNumber.toString())
console.log(bigNumber.toString()[30]) // result
let bigNumber2 = BigInt('1234567891111111111111111111111111111') // <-- also works as a string, in case you can't use the literal for some reason
console.log(bigNumber2.toString())
console.log(bigNumber2.toString()[30]) // result

Which javascript function can be used to covert an array of characters into a number?

There are a few Javascript functions available to convert anything into its equivalent number. Number() operates on an Object, valueOf(), parseFloat, parseInt() are also available.
I have an array which stores numbers 0-9 and decimal point, the elements of the array taken together represents a number. What is the best way to convert this array into a number, whole or fractional?
EDIT: Apologies if I were not clear before. The array, holding the 0-9 characters and possibly a decimal point, could represent either a whole number(without the decimal obviously) or a fractional number. So please suggest something that works for both cases. Thanks.
Try this
var a = [1,2,3,".",2,3];
var num = +a.join("");
What is the best way to convert this array into a number, whole or fractional?
Firstly to combine your array elements you should use Array.join().
You will then have a concatenated variable of your values and decimal. To convert this to a whole number, use parseInt(), and to a floating point number use parseFloat(). You can use the unary + operator (which acts similarly to parseFloat), however in my opinion it is not the best choice semantically here, as you seem to want a specific type of number returned.
Example:
var arr = ['1','.','9','1'];
var concat = arr.join();
var whole = parseInt(concat);
var floating = parseFloat(concat);
Also, parseInt will trim the decimal portion of your number, so if you need rounding you can use:
var rounded = Math.round(parseFloat(concat));
You could use the split property of the string. It splits all the characters into an zero based array.
var charSplits = "this is getting split.";
var splitArr = charSplits.split();
Console.log(splitArr);
// this returns i
Console.log(splitArr[2]);

JavaScript Math.min returns wrong value

I'm using John Resig's function to find min value in an array but it returns somehow floored value.
Here's a demo and here's the code.
var arr = Math.min.apply(Math, [310127563311820800, 310127563190202368, 310127563110502401, 310127562443595776, 310127562326163457, 310127561751556097]);
document.write(arr);
Can you explain me what happens and why it's returning wrong(floored) value?
The problem isn't in finding the min but in using those numbers. You can't represent them as numbers in JavaScript as integers can only be completely kept between -9007199254740992 and +9007199254740992.
It's because all numbers in JavaScript are double precision IEEE754 floats and the size of the mantissa is 53.
See more details in ECMAScript specification on the number type :
Note that all the positive and negative integers whose magnitude is no
greater than 253 are representable in the Number type (indeed, the
integer 0 has two representations, +0 and -0).
To deal with those numbers (and find their min), you need to use another representation than the native JavaScript number. Hopefully, there are many libraries dealing with big numbers, for example bignum (but you should google and pick the one you like).
You will lose precision in javascript unless you make the input strings of digits.
If they are all positive integers you can sort them and return the lowest indexed element, remembering that a string with more digits must be larger than one with fewer-
var input= ['310127563311820800', '310127563190202368', '310127563110502401',
'310127562443595776', '310127562326163457', '310127561751556097'];
var minim= input.slice(0).sort(function(a, b){
if(a=== b) return 0;
if(a.length!= b.length) return a.length-b.length;
return a>b? 1:-1;
})[0];
alert(minim);
/* returned value: (String)
310127561751556097
*/
You can skip the slice(0) bit if you don't need to keep the original in its order.

Categories