Weird Javascript Calculation - javascript

Why when using javascript does this formula return -Infinity
793 * ( 1 - ( 1 + Math.pow(.032 / 12 , (-1 * (30 * 12))))) / (.032 / 12);

Because it's the correct answer!
The Math.pow part is equivalent to the following:
Math.pow(0.0026666666666666666, -360)
Which has the result Infinity
Then, you multiply it by -1, and multiply / divide it by positive numbers, which doesn't affect the result considering it's -Infinity.

The gist of it comes from Math.pow(.032 / 12 , (-1 * (30 * 12))). You're taking a very small number (0.032/12) and taking it to a large, negative power (-1 * 30 * 12).
Mathematically, that's the same as taking a normal-sized number and taking it to a large number -- you're basically calculating 375**360, which clearly is infinity. The rest of the numbers just end up making it -Infinity instead of Infinity.

According to MDN,
The MAX_VALUE property has a value of approximately 1.79E+308, or 21024. Values larger than MAX_VALUE are represented as "Infinity".
This part of your calculation Math.pow(.032 / 12 , (-1 * (30 * 12))) equals
4.4797768587048112310581443943723309108149091701091649 × 10^926
Which is larger than Number.MAX_VALUE, so it is represented as Infinity.
After that, you're basically just adding and flipping the sign.

Related

Can I safely use the Number type in javascript for calculations with 2 decimal places?

I know that certain numbers will get slight variations from their original value.
Eg. 0.1 + 0.2 -> 0.30000000000000004.
But if I do Math.round(0.30000000000000004 * 100) / 100, I will get the correct answer -> 0.3.
I ran a Javascript test and found that the results will accurate at least up to 1e+10.
Are there any caveats to doing this?
If I use Math.round(result * 100) / 100 after every calculation, can I be sure the results will be accurate?
The only calculations I plan to make are addition and multiplication and all numbers will only have 2 decimal places as confirmed by Math.round(n * 100) / 100.
I don't need the numbers to be accurate over about $1000.
Can I be sure my results will be accurate to the nearest cent?
You may face some errors while using Math.round(n * 100) / 100 .
It won't always give your expected result, as for example:
console.log(Math.round(0.145*100)/100)
the expected result would be 0.15. it happens because there are some floats like 0.145 * 100 = 14.499999999999998
i suggest using different approaches, such as:
expected-round
Number.EPSILON
more on that topic:
How to round to at most 2 decimal places, if necessary?
How to format a float in javascript?

Flooring a random exponential value for a cookie key

Is it possible to get string with length of 17 by using such code?
We're saving cookie in a client's browser and then get it from this browser.
function getPartnerVisitorId() {
var pvid = cookies.get('pvid') || Math.floor(Math.random() * Math.pow(10, 15)).toString();
cookies.setOnRoot('pvid', pvid, 365 * 24 * 60 * 60);
return pvid;
};
We think that "pvid" should be maximum of 16 digits length, but sometimes (about 5% of cookies) we get 17 digits length of this cookie.
Also we've noticed that all of strange cookies are even numbers and most of them (75%) had zero as the last digit
The issue that you're dealing with has to do the nature of IEEE 754 floating point numbers - the type used to hold Number in JavaScript, double in Java and C, etc. These numbers are stored in a sort of scientific notation, in the form of
[+/-] 1.[some value] * 2^[some other value].
This results in you getting about 15 significant decimal digits that are especially adept at expressing powers of 2.
By multiplying Math.random() by Math.pow(10,15), you are encountering two problems with this scheme:
You are running out of digits, hence truncating the last few at the bottom (hence why your numbers are always even)
You are trying to represent a power of 10, which it cannot always do accurately (hence why you are sometimes getting 17-digit keys).
To fix these problems and get the constant-length random keys you want, do two things:
Multiply Math.random() by Math.pow(2,x) (where x is a number you experiment with to find the right length) - 2^anything can always be accruately expressed by floating point numbers.
In the toString(), method, insert an integer parameter that is a power of 2 (such as 8 or 16) - this will cause the number to be converted to a string with the base-8 or base-16 number system. This will prevent variable length keys and also prevent rounding.
var pvid = cookies.get('pvid') || Math.floor(Math.random() * Math.pow(8, 15)).toString(8);

understanding the modulus operator in javascript

Twenty modulus six is equal to two, which is the remainder but how to know the the modulus is using the 3 to perform the operation?
20 % 6 = 2
You can use
Math.floor(20 / 6);
for this. It rounds down so you have the largest number possible without decimals.
If you want the quotient, you just have to truncate the division
Math.trunc(20/6) //Return 3
Reference
Modulus is not using the 3, it simply knows that:
20 / 6 = 3, with a remainder of 2
=> 20 % 6 = 2
If you want the 3, you just need the expression:
Math.floor(20 / 6)
(or possibly Math.trunc depending on how you want negative numbers handled - floor rounds towards negative infinity, trunc rounds toward zero).

Why isn't Math.floor((Math.random() * 999999) + 100000) reliable for producing 6 digit numbers?

I've looked at some other questions, but they all have disjointed and confusing answers.
I want to have a random 6 digits, which most of the time this scripts work - it does however also produce 7 digit numbers about 20% of the time.
Math.floor((Math.random() * 999999) + 100000)
My questions:
Why?
Correct way of avoiding this?
Please don't suggest using substring or something similar as it is a bit of a hack
This is a simple calculation range error. NB: text below uses [ and ] to represent an inclusive range and ( or ) to represent an exclusive range.
To get the range [100000, 999999] which in integer math is equivalent to [100000, 1000000) you need to get a number in the range [0, 900000) and then add 100000, e.g.
Math.floor(900000 * Math.random()) + 100000
The factor is 900000 rather than 899999 because the Math.random() function produces numbers in the range [0, 1), i.e. not including 1 itself.
well the problem is in your math.
Math.random produces a float from 0.0 to 1.0 . In the worst case you multiply 1.0 with 999999 and add another 100000 . this results in 1099999.0 (for the biggest case).
this line should always produce a 6-digit number
Math.floor((Math.random() * 899999) + 100000)

Negative Number to Non-Integer Power in Javascript

I'm writing a script that has to do something like this at one point: Math.pow(-2,1.5). The result should be approximately -2.82843, but instead, Javascript returns NaN. (I tried this in both Google Chrome 17 and Mozilla Firefox 11.) If the exponent is an integer, such as in Math.pow(-2,3), then Javascript will return the right answer, which, in this case, is -8. Positive numbers also correctly raise to non-integer powers; Math.pow(2,1.5) evaluates to approximately 2.8284271247461903. Is there any way that I can get Javascript to calculate the value of a negative number to a non-integer power?
Math.pow(-2, 1.5) returns NaN because there is no real number which equals -2 taken to the power 1.5. There is a complex number with this property, but Math.pow() doesn't do calculations using complex numbers.
This simple transformation demonstrates that this is the case:
(-2)1.5 = (-2)1 * (-2)0.5 = (-2) * sqrt(-2) = (-2) * i * sqrt(2) = -2i * sqrt(2)

Categories