NodeJs calculation gone wrong - javascript

I have if statement like:
if((gotPrice * price.value).toFixed(0) >= answers.MINIMUM_BUY_AMOUNT) {
...
}
Results are
(gotPrice * price.value).toFixed(0) = 0
and
answers.MINIMUM_BUY_AMOUNT = 200
Then it fall to true! not sure in what world 0 is greater or equal to 200!!
I also tried this way but results was the same
if((gotPrice * price.value).toFixed(0) >= Number(answers.MINIMUM_BUY_AMOUNT).toFixed(0)) {
...
}
sample:
var x = 0.3431;
var y = 1.5467;
var z = '200';
console.log((x * y).toFixed(0) >= z); // false (but in my case says true!)
Any suggestions?

ToFixed converts number to string, calculations should be done with numbers
var x = 0.3431;
var y = 1.5467;
var z = parseInt('200');
console.log(Math.round(x * y) >= z);

Related

How to calculate the square root without using library and built-in methods in Javascript?

Please help me to write a function to compute the square root of positive real numbers using the formula:
x i+1 = (1/2) * (xi + (A / x1)),
where 'A' - input real number.
On the zero iteration next statements have been taken x0 = A
The error should be at least 10-6
Output
sqrt (2) = 1.414
sqrt (9) = 3
sqrt (25) = 5
You could take xi (x) and the new value of xi + 1 (x1) and check if the values are equal. Then end the series and return that value.
For starting, you need an apporopriate value like the half of the given value.
function sqrt(a) {
var x,
x1 = a / 2;
do {
x = x1;
x1 = (x + (a / x)) / 2;
} while (x !== x1);
return x;
}
console.log(sqrt (2)); // 1.414
console.log(sqrt (9)); // 3
console.log(sqrt (25)); // 5
You can also use bisection - a more general method for solving problems:
var sqrt = function(n) {
if (n<0) {
throw "are you kidding?! we are REAL here.";
}
if (n === 0) {
return 0;
}
var bisect = function(l,r) {
var avg = (l+r)/2;
if (r-l<0.00000001) {
return (l+r)/2;
}
if (avg*avg > n) {
return bisect(l, avg);
} else if (avg*avg < n) {
return bisect(avg, r);
}
}
return bisect(0, n < 1 ? 1 : n);
}

why isn't this js code for finding derivative working?

When ran it gives an alert box with undefined written, Can you help me debug this code? I am unable to find the correct error you can check it and please help me. It must give the derivative at point x=10 for f(x)=x^2+1 by using smaller and smaller h till desired accuracy is reached.
function f(x) {
return x * x + 1;
}
var iter = [];
var h = 0;
var ddx = 0;
iter[0] = ((f(10 + h) - f(10)) / h);
function d_dx(p) {
for (i = 1; i < 20; i++) {
iter[i] = ((f(p + h) - f(p)) / h);
if (iter[i] = iter[i - 1]) {
break;
var ddx = iter[i];
} else {
h = h / 2;
}
}
return ddx;
}
console.log(d_dx(10));
Your iter array will be NaN. h will be always 0 and you divide by 0.
if (iter[i] = iter[i - 1]) statement is wrong, you should use === to compare values. You cannot use break in if if you want to loop this code multiple times. There are many mistakes in your code.
var ddx is not reachable after break. That's why it is returning undefined. And one more thing, you are using assignment instead of conditional expression.(correct comparison is - if (iter[i] == iter[i - 1])) )
You have used var ddx out of scope while you are returning the ddx.

Generate random number between range including negative in javascript

I am trying to set a function that creates a random number between a range
I need to make it working with negative values so I can do
randomBetweenRange( 10, 20)
randomBetweenRange(-10, 10)
randomBetweenRange(-20, -10)
This is what I am trying, it is a bit confusing and at the moment randomBetweenRange(-20, -10) is not working..
function randomBetweenRange(a, b){
var neg;
var pos;
if(a < 0){
neg = Math.abs(a) + 1;
pos = (b * 2) - 1;
}else{
neg = -Math.abs(a) + 1;
var pos = b;
}
var includeZero = true;
var result;
do result = Math.ceil(Math.random() * (pos + neg)) - neg;
while (includeZero === false && result === 0);
return result;
}
How can I make it working?
ASSUMING you will always have the little value on first, this code will do the tricks, see the comment below and don't hesitate to ask !
var a=parseInt(prompt("First value"));
var b=parseInt(prompt("Second value"));
var result = 0;
// Here, b - a will get the interval for any pos+neg value.
result = Math.floor(Math.random() * (b - a)) + a;
/* First case is we got two neg value
* We make the little one pos to get the intervale
* Due to this, we use - a to set the start
*/
if(a < 0) {
if(b < 0) {
a = Math.abs(a);
result = Math.floor(Math.random() * (a + b)) - a;
}
/* Second case is we got two neg value
* We make the little one neg to get the intervale
* Due to this, we use - a to set the start
*/
} else {
if(b > 0) {
a = a*-1;
result = Math.floor(Math.random() * (a + b)) - a;
}
}
console.log("A : "+a+" | B : "+b+" | Int : "+(a+b)+"/"+Math.abs((a-b)));
console.log(result);
You have declared the variable 'pos' in the beginning itself. Then why do you declare it in the 'else' part? ( var pos = b;)
Hence, for this statement,
do result = Math.ceil(Math.random() * (pos + neg)) - neg;
'pos' will not have any value.
do result = Math.ceil(Math.random() * (pos + neg)) - neg;
Specifically Math.random() * (pos + neg) returns the wrong range. If pos = -20 and neg = -30, the range between pos and neg should be 10, but your operation returns -50. You should also add one to the range because its technically the amount of possibilities (ex: if you want to generate your function to return {0,1}, the range between pos and neg is 1, but there are two possibilities of numbers to return) and subtract another 1 from result because you're using Math.ceil
Your else clause also redeclares var pos
If you want to generate a number between -50 and 50 - Get a random number between 0 and 100 then subtract 50
var randomNumber = Math.floor(Math.random() * 101) - 50;
console.log(randomNumber);

Tanh returning NaN for large input?

In my node.js program, I ran this code
console.log(Math.tanh(-858.625086043538));
and it returned NaN. Yet, tanh (hyperbolic tangent) http://mathworld.wolfram.com/HyperbolicTangent.html is defined for all x. It should just return -1, but its giving NaN. Does anyone know whats wrong?
Thanks
Looks like a bad implementation in Node.js (v5.4.1) version of V8 (4.6.85.31) which is taking e^(+/-x) which, for an input that larger, results in the return of (-Infinity / Infinity) which, further, is NaN.
The good news is this was fixed in V8 version v4.8.87 with a commit that moved to a js fdlibm port. This is why it works in your current-version Chrome DevTools.
If you cannot wait until Node.js pulls in the latest V8, you can port over the current V8 implementation into your own code (which is based on this port of fdlibm), which seems to work fine. You just run the risk of any fixes or changes to the real V8 Math.tanh that may occur in the future. Here's the V8/fdlibm port:
Math.tanh = function (x) {
x = x * 1; // Convert to number.
// x is Infinity or NaN
if (!Math.abs(x) === Infinity) {
if (x > 0) return 1;
if (x < 0) return -1;
return x;
}
var ax = Math.abs(x);
var z;
// |x| < 22
if (ax < 22) {
var twoM55 = 2.77555756156289135105e-17; // 2^-55, empty lower half
if (ax < twoM55) {
// |x| < 2^-55, tanh(small) = small.
return x;
}
if (ax >= 1) {
// |x| >= 1
var t = Math.exp(2 * ax);
z = 1 - 2 / (t + 2);
} else {
var t = Math.exp(-2 * ax);
z = -t / (t + 2);
}
} else {
// |x| > 22, return +/- 1
z = 1;
}
return (x >= 0) ? z : -z;
};

Cumulative distribution function in Javascript

I am searching for a way to calculate the Cumulative distribution function in Javascript. Are there classes which have implemented this? Do you have an idea to get this to work? It does not need to be 100% percent accurate but I need a good idea of the value.
http://en.wikipedia.org/wiki/Cumulative_distribution_function
I was able to write my own function with the help of Is there an easily available implementation of erf() for Python? and the knowledge from wikipedia.
The calculation is not 100% correct as it is just a approximation.
function normalcdf(mean, sigma, to)
{
var z = (to-mean)/Math.sqrt(2*sigma*sigma);
var t = 1/(1+0.3275911*Math.abs(z));
var a1 = 0.254829592;
var a2 = -0.284496736;
var a3 = 1.421413741;
var a4 = -1.453152027;
var a5 = 1.061405429;
var erf = 1-(((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*Math.exp(-z*z);
var sign = 1;
if(z < 0)
{
sign = -1;
}
return (1/2)*(1+sign*erf);
}
normalcdf(30, 25, 1.4241); //-> 0.12651187738346226
//wolframalpha.com 0.12651200000000000
The math.js library provides an erf function. Based on a definition found at Wolfram Alpha , the cdfNormalfunction can be implemented like this in Javascript:
const mathjs = require('mathjs')
function cdfNormal (x, mean, standardDeviation) {
return (1 - mathjs.erf((mean - x ) / (Math.sqrt(2) * standardDeviation))) / 2
}
In the node.js console:
> console.log(cdfNormal(5, 30, 25))
> 0.15865525393145707 // Equal to Wolfram Alpha's result at: https://sandbox.open.wolframcloud.com/app/objects/4935c1cb-c245-4d8d-9668-4d353ad714ec#sidebar=compute
This formula will give the correct normal CDF unlike the currently accepted answer
function ncdf(x, mean, std) {
var x = (x - mean) / std
var t = 1 / (1 + .2315419 * Math.abs(x))
var d =.3989423 * Math.exp( -x * x / 2)
var prob = d * t * (.3193815 + t * ( -.3565638 + t * (1.781478 + t * (-1.821256 + t * 1.330274))))
if( x > 0 ) prob = 1 - prob
return prob
}
This answer comes from math.ucla.edu
Due to some needs in the past, i put together an implementation of distribution function in javascript. my library is available at github. You can take a look at https://github.com/chen0040/js-stats
it provides javascript implementation of CDF and inverse CDF for Normal distribution, Student's T distribution, F distribution and Chi-Square Distribution
To use the js lib for obtaining CDF and inverse CDF:
jsstats = require('js-stats');
//====================NORMAL DISTRIBUTION====================//
var mu = 0.0; // mean
var sd = 1.0; // standard deviation
var normal_distribution = new jsstats.NormalDistribution(mu, sd);
var X = 10.0; // point estimate value
var p = normal_distribution.cumulativeProbability(X); // cumulative probability
var p = 0.7; // cumulative probability
var X = normal_distribution.invCumulativeProbability(p); // point estimate value
//====================T DISTRIBUTION====================//
var df = 10; // degrees of freedom for t-distribution
var t_distribution = new jsstats.TDistribution(df);
var t_df = 10.0; // point estimate or test statistic
var p = t_distribution.cumulativeProbability(t_df); // cumulative probability
var p = 0.7;
var t_df = t_distribution.invCumulativeProbability(p); // point estimate or test statistic
//====================F DISTRIBUTION====================//
var df1 = 10; // degrees of freedom for f-distribution
var df2 = 20; // degrees of freedom for f-distribution
var f_distribution = new jsstats.FDistribution(df1, df2);
var F = 10.0; // point estimate or test statistic
var p = f_distribution.cumulativeProbability(F); // cumulative probability
//====================Chi Square DISTRIBUTION====================//
var df = 10; // degrees of freedom for cs-distribution
var cs_distribution = new jsstats.ChiSquareDistribution(df);
var X = 10.0; // point estimate or test statistic
var p = cs_distribution.cumulativeProbability(X); // cumulative probability
This is a brute force implementation, but accurate to more digits of precision. The approximation above is accurate within 10^-7. My implementation runs slower (700 nano-sec) but is accurate within 10^-14. normal(25,30,1.4241) === 0.00022322110257305683, vs wolfram's 0.000223221102572082.
It takes the power series of the standard normal pdf, i.e. the bell-curve, and then integrates the series.
I originally wrote this in C, so I concede some of the optimizations might seem silly in Javascript.
function normal(x, mu, sigma) {
return stdNormal((x-mu)/sigma);
}
function stdNormal(z) {
var j, k, kMax, m, values, total, subtotal, item, z2, z4, a, b;
// Power series is not stable at these extreme tail scenarios
if (z < -6) { return 0; }
if (z > 6) { return 1; }
m = 1; // m(k) == (2**k)/factorial(k)
b = z; // b(k) == z ** (2*k + 1)
z2 = z * z; // cache of z squared
z4 = z2 * z2; // cache of z to the 4th
values = [];
// Compute the power series in groups of two terms.
// This reduces floating point errors because the series
// alternates between positive and negative.
for (k=0; k<100; k+=2) {
a = 2*k + 1;
item = b / (a*m);
item *= (1 - (a*z2)/((a+1)*(a+2)));
values.push(item);
m *= (4*(k+1)*(k+2));
b *= z4;
}
// Add the smallest terms to the total first that
// way we minimize the floating point errors.
total = 0;
for (k=49; k>=0; k--) {
total += values[k];
}
// Multiply total by 1/sqrt(2*PI)
// Then add 0.5 so that stdNormal(0) === 0.5
return 0.5 + 0.3989422804014327 * total;
}
You can also take a look here, it's a scientific calculator implemented in javascript, it includes erf and its author claims no copyright on the implementation.

Categories