When I try to add two integers together, the integer just stays at what it originally was. It's difficult to explain, so here's my code:
var levelRewardsID = parseInt(resultData[0].levelRewardsHighestID)
var levelRewardsIDIncrease = Math.floor(Math.random()*9)+1
var newLevelRewardsID = levelRewardsID+levelRewardsIDIncrease
console.log(levelRewardsID)
console.log(levelRewardsIDIncrease)
console.log(newLevelRewardsID)
if (!isNaN(levelRewardsID)) {
console.log("not NAN")
}
if (!isNaN(levelRewardsIDIncrease)) {
console.log("not NAN 2")
}
if (!isNaN(newLevelRewardsID)) {
console.log("not NAN 3")
}
Console:
89819672607051330000
6
89819672607051330000
not NAN
not NAN 2
not NAN 3
So as you can see, everything is an integer. So that can't be the issue. Yet when I try to do var newLevelRewardsID = levelRewardsID+levelRewardsIDIncrease, the output is the same as levelRewardsID... I'm not sure what I did wrong but if anyone knows, do let me know. Thanks!
Note: I'm using Node.JS version 9.1.0 (latest as of posting this) if that helps
I think you reach the javascript number limit which seems to be 9007199254740992 and 89819672607051330000 > 9007199254740992.
See What is JavaScript's highest integer value that a number can go to without losing precision?
Related
I'm working on the Project Euler problems (currently question 13).
For this question I have to find the first 10 digits of the sum of 100 numbers all of a size similar to this:
91,942,213,363,574,161,572,522,430,563,301,811,072,406,154,908,250
I think I could use something like Java's BigInteger, but I started solving the problems in JavaScript (I'm trying to boost my js abilities for work), and I would like to continue using it, even to solve this problem.
I'd like to stick to pure JS if possible.
Javascript recently got a new primitive data type BigInt (stage 4 proposal as of January 2020).
https://github.com/tc39/proposal-bigint
Chrome, Firefox and few other browsers have started supporting this in newer versions (check compatibility here), while other browsers are still implementing it.
https://developers.google.com/web/updates/2018/05/bigint
Basically it can be declared using either literals like
var a = 1n;
or
var b = BigInt('22222222222222222222222222222222');
Math operators don't do auto conversion between BigInt and Number, so
1 + 1n
will throw an error.
You are going to need a javascript based BigInteger library. There are many to choose from. Here is one https://github.com/peterolson/BigInteger.js
You can use it like this
var n = bigInt("91942213363574161572522430563301811072406154908250")
.plus("91942213363574161572522430563301811072406154908250");
Surprisingly, sticking all the values in an array and adding them all together and just taking the first 10 digits worked. I must have had a typo somewhere in my code when it didn't work before.
I'm sure that doing something this simple wouldn't work in all cases (like those #AlexMcmillan and #zerkms have been debating about). I think the safest bet is the BigInteger library mentioned by #bhspencer, but it seems like adding the first x significant digits with y digits as a buffer might also be worth a shot in some cases.
I did this using an array and updating all entries with a function.
function f(a) {
for (let i = 0; i < a.length - 1; i++) {
a[i + 1] = a[i + 1] + parseInt(a[i] / 10);
a[i] = a[i] % 10;
}
return a;
}
// remember to init the array with enough elements for all digits
var a = Array(200);
a.fill(0);
a[0] = 1;
Here is a JSFiddle with the code for problem 20.
You could always convert your sum to a string, rip out the . and grab the result - something like this:
var sum = 2384762348723648237462348;
sum = sum.toString(); // "2.3847623487236483e+24"
// Rip out the "."
sum = sum.substr(0, 1) + sum.substr(2);
// Grab the first 10 characters
var firstTen = sum.substr(0, 10);
I'm trying to find the largest number by finding the point at which the JavaScript number line wraps around. E.g., if it could only hold numbers 0, 1, 127 then I'd find 127 by using the fact that "127 + 1 = 0". So I made a function
function getLargestNumber ( )
{
var somethingBig = 12939123, last = (somethingBig - 1);
while ( ++somethingBig > ++last );
return last;
}
but that's causing an infinite loop (or crashing the browser for some other reason).
Is there anything wrong with the logic of my function?
JavaScript numbers are always stored as floating point numbers, not integers like in C. Floating point numbers don't "wrap around" the same way that a C integer will.
This might help you What is JavaScript's highest integer value that a Number can go to without losing precision?
It looks like the while loop will run forever because you are always incrementing both somethingBig and last, therefore somethingBig will always be larger:
while ( ++somethingBig > ++last );
I'm not sure exactly what you are trying to accomplish but this would be the cause of the infinite loop.
Hope this helps!
This question already has answers here:
What is JavaScript's highest integer value that a number can go to without losing precision?
(21 answers)
Closed 7 years ago.
Why is it apparently safe to use numbers as integers in Javascript? What I mean is that a loop such as the one below is generally "trusted" to run the expected number of times even though the final loop requires an exact compare of (10000 == 10000) when these two values are floats and not ints. Is there some sort of built-in rounding feature that makes this safe and reliable -- or is this horrible and untrustworthy coding? Thanks.
--edit--
It is interesting that there is a declared safe integer range. I was not aware of MAX_SAFE_INTEGER. We all know the standard whine that 2 + 2 = 3.9999. I note that MAX_SAFE_INTEGER is listed as ECMAScript-6 so does this imply that IEEE-754 does not actually mention a safe integer range?
var cnt = 0;
for (var i=0 ; i<=10000 ; i++){
// loop 10001 times
cnt++;
}
alert('cnt = '+ cnt);
IEEE-754 double-precision floating point numbers (the kind used by JavaScript) have a very wide range over which they precisely represent integers, specifically -9,007,199,254,740,991 through 9,007,199,254,740,991. (Those values are being added to JavaScript's Number function as constants: MIN_SAFE_INTEGER and MAX_SAFE_INTEGER.) Outside that range, you could indeed run into trouble.
In fact, if it weren't for safety, this loop would never end:
var n, safety;
safety = 0;
for (n = 9007199254740990; n != 9007199254740999; ++n) {
if (++safety === 20) { // Long after `n` should have matched
snippet.log("Had to break out!");
break;
}
snippet.log("n = " + n);
}
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Firstly, the final loop doesn't require the two values to be equal. Just that i is less than 10000.
Secondly, the Number type in JavaScript holds integer values accurately up (and down) to a point. You can access the Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER properties to see what the safe range is for your browser/engine.
And if you want to check if an instance of Number is an integer, just use the Number.isInteger() method.
var i = 10, e = document.getElementById('message');
if(Number.isInteger(i)) {
e.innerHTML = "i is an integer";
} else {
e.innerHTML = "i is not an integer";
}
<div id='message'></div>
I'm facing a really strange problem comparing integer in Javascript. I have an array of numbers and I want to check if the current number in a loop is smaller than the previous one. To do so, I save the "current" number as "previous", so I can check them in the next loop. The function runs as expected, EXCEPT every time the current and the previous number have a different number of digits: in this case, the code doesn't see the actually smaller number as being smaller than the previous one.
For example:
111 < 120 ? ---> YES!
106 < 111 ? ---> YES!
98 < 106 ? ---> NO!
76 < 98 ? ---> YES!
5 < 76 ? ---> NO!
I'm unable to find anything strange in the code I'm using, as it is quite simple:
for(var j=0;j<arrScores.length;j++)
{
if(arrScores[j][0] < scoreAnt)
{
console.log("Smaller!");
}
scoreAnt = arrScores[j][0];
}
I've tried using parseInt() in both values, but nothing changes... Checking the length of both numbers using scoreAnt.toString().length returns a length of 1, no matter which number it is (100, 34 or 156798), and the same for arrScores[j][0]. I've also logged the whole thing to check that the numbers are the expected ones, and they are (the numbers used in the example are some of the ones I'm using)...
Any clue on what can be happening? I'm really lost with this, becuase it makes no sense for me...
Thanks in advance for your time and effort! :)
You always do scoreAnt = arrScores[j][0]; in the loop; but you should only do that if arrScores[j] is smaller; i.e. inside the inner curly braces.
for(var j=0;j<arrScores.length;j++)
{
if(arrScores[j][0] < scoreAnt)
{
console.log("Smaller!");
scoreAnt = arrScores[j][0];
}
}
Well, don't even know why, but after changing something relating the CORS of the server where these numbers came from (but not modifying the numbers at all), the comparison seems to work as expected... Have no clue about what might have changed! :S However, now it works correctly...
I am trying to generate randomly basic math operations(addition, subtractions, multiplication and division) and sometime my function returns NaN.
I used function parseInt(), but I still have the same problem. I will appreciate if anybody can help me with any suggestion.
Thank you in advance!
Here is my code:
function randNum(min,max)
{
var num = min+Math.floor((Math.random()*(max-min+1)));
return num;
}
var choose, operator, firstNum, secondNum,rightAnswer;
function getProb()
{
var chooseOp=randNum(1,4);
choose=parseInt(chooseOp);
if (choose==1)
{
oprator="+";
var choose1=randNum(0,10);
var choose2=randNum(0,10);
firstNum=parseInt(choose1);
secondNum=parseInt(choose2);
document.getElementById("mathProb").innerHTML=firstNum+operator+secondNum+"=";
rightAnswer=choose1 + choose2;
}
else if (choose==2)
{
operator="-";
var choose1=randNum(0,10);
var choose2=randNum(0,10);
firstNum=parseInt(choose1);
secondNum=parseInt(choose2);
document.getElementById("mathProb").innerHTML=firstNum+operator+secondNum+"=";
rightAnswer=firstNum - secondNum;
}
else if (choose==3)
{
operator="x";
var choose1=randNum(0,10);
var choose2=randNum(0,10);
firstNum=parseInt(choose1);
secondNum=parseInt(choose2);
document.getElementById("mathProb").innerHTML=firstNum+operator+secondNum+"=";
rightAnswer=choose1 * choose2;
}
else if (choose==4)
{
operator="/";
var choose1=randNum(0,10);
var choose2=randNum(0,10);
firstNum=parseInt(choose1);
secondNum=parseInt(choose2);
document.getElementById("mathProb").innerHTML=firstNum+operator+secondNum+"=";
rightAnswer=choose1/choose2;
}
}
When choose==1, operator is misspelled as oprator. If you correct it, problem is solved
http://jsfiddle.net/uERwd/2/
UPDATE:
Your code can be made shorter as: http://jsfiddle.net/uERwd/3/
Your division operation has the possibility of dividing by zero, which would return NaN.
Your "NaN" bug is here :
rightAnswer=choose1/choose2;
choose1 an choose2 are integer in [0, 1].
One time over 121, you're dividing 0 by 0, wich gives NaN.
And a little less than one time over 11, you're dividing a not null number by 0, wich gives Infinity.
You need to specify with a number that represent numeral system, tipically, base 10
http://www.w3schools.com/jsref/jsref_parseint.asp
Add the number 10 to the function call like this
firstNum = parseInt(choose1, 10);
When you randomly choose the division operator, it's possible to have zero come out for both choose1 and choose1, which means you attempt to evaluate rightAnswer = 0 / 0;. In Javascript, this equals NaN. Additionally, and this should happen more often, if you choose zero in the denominator any other number in the numerator the answer will come out as Infinity. Of course, zero over anything is zero.
It's a simple syntax error:
oprator="+"; // should be `operator`
That's why this statement...
firstNum+operator+secondNum+"=";
... will actually be evaluated as ...
firstNum+undefined+secondNum+"=";
The first pair will give you NaN, NaN + Number will be a NaN again, and NaN + String ("=") will result in NaN converted to string, then appended with '=' (hence resulting 'NaN=').
I'd strongly recommend placing "use strict"; line at the beginning of your scripts to catch such errors. With this, you'll get an error:
ReferenceError: assignment to undeclared variable oprator
... and won't need to make SO parse your script for errors instead. )
Sidenotes, I have plenty of them:
your randNum function will return you a Number, so no need to use parseInt (you may have to convert arguments of this function, but even that seems not to be necessary here) on its result;
if you divide by zero, you get Infinity; if you divide zero by zero, you get NaN as a result; be prepared or adjust the minimums. )
you violate DRY principle, repeating most of the statements outputting a result, why don't convert them into a function? Check this snippet (started by #sv_in, completed by me) for example how to do it.