Javascript - strange math output - javascript

This is my JavaScript:
function straava() {
var input = document.getElementById('input').value
var r1 = document.getElementById('r1').value
var r2 = document.getElementById('r2').value
document.getElementById("output").innerHTML = r2 / (r1 + r2) * input;
}
Given values:
input = 5
r1 = 1000
r2 = 1000
The expected output is 2.5, but this function produces 0.0004999500049995. Why is that?

Your variables are strings. So here is what happens:
"1000" / ("1000" + "1000") * "5";
"1000" / "10001000" * "5";
// 0.0004999500049995
The + (addition) operator concatenates strings instead of adding them, hence the incorrect result.
Convert your "numbers" to Number; using parseInt / parseFloat functions, the (unary) + operator or Number function:
var input = parseInt(document.getElementById('input').value, 10);
var r1 = parseInt(document.getElementById('r1').value, 10);
var r2 = parseInt(document.getElementById('r2').value, 10);

You're not parsing the values to numbers, so it does the calculations on the strings. This happens because getting element values, through the use of .value, will return type string.
function straava() {
var input = parseInt(document.getElementById('input').value);
var r1 = parseInt(document.getElementById('r1').value);
var r2 = parseInt(document.getElementById('r2').value);
document.getElementById("output").innerHTML = r2 / (r1 + r2) * input;
}
Below is an example of the different outputs, using both strings and ints.
function straava(p1, p2, p3) {
var input = p1 //document.getElementById('input').value
var r1 = p2 //document.getElementById('r1').value
var r2 = p3 //document.getElementById('r2').value
return (r2 / (r1 + r2) * input);
}
document.getElementById('output1').innerHTML = straava('5','1000','1000');
document.getElementById('output2').innerHTML = straava(5,1000,1000);
Using strings as parameters: <span id="output1"></span><br/>
Using integers as parameters: <span id="output2"></span>

Related

Google Sheets NORMDIST( x, mean, standard deviation, cumulative T/F) to JavaScript

Google Sheets has the NORMDIST( x, mean, standard deviation, cumulative T/F) function. I have not been able to find something equivalent in JavaScript. The examples I've found do not allow for all the variables that are in the Google function or I don't have the understanding to implement them.
I am trying to write a reiterative JavaScript function to replace a set of reiterative Google Sheets calculations and need something like this;
x = NORMDIST(x,0,1, TRUE);
y = NORMDIST(x,0,1, FALSE);
At a high-level, there's two things that the NORMDIST function can do: calculate the Normal Distribution's PDF when false is supplied as the last parameter and CDF when true is supplied.
The PDF part is easy: just follow the formula given on Wikipedia for Normal Distribution.
The CDF part is less trivial as it's a non-elementary integral. Your best shot is to find some open-source implementation and translate it into JS. (Preferably a non-iterative one.) It won't be 100% exact due to roundoff errors, but it can get you extremely close. I found one here.
Here's what I came up with:
function _getNDistPDF(x, mean, stdev)
{
const sqrt2PI = Math.SQRT2 * Math.sqrt(Math.PI);
let frac = (x - mean) / stdev;
return Math.exp(-.5 * frac * frac) / (sqrt2PI * stdev);
}
// Adapted from https://people.sc.fsu.edu/~jburkardt/c_src/asa066/alnorm.c
function _getNDistCDF(x, mean, stdev)
{
const a1 = 5.75885480458;
const a2 = 2.62433121679;
const a3 = 5.92885724438;
const b1 = -29.8213557807;
const b2 = 48.6959930692;
const c1 = -0.000000038052;
const c2 = 0.000398064794;
const c3 = -0.151679116635;
const c4 = 4.8385912808;
const c5 = 0.742380924027;
const c6 = 3.99019417011;
const con = 1.28;
const d1 = 1.00000615302;
const d2 = 1.98615381364;
const d3 = 5.29330324926;
const d4 = -15.1508972451;
const d5 = 30.789933034;
const ltone = 7.0;
const p = 0.398942280444;
const q = 0.39990348504;
const r = 0.398942280385;
const utzero = 18.66;
let up = false;
let value;
let y;
// For non-standard NDist
let z = (x - mean) / stdev;
if (z < 0)
{
up = true;
z = -z;
}
if (ltone < z && (!up || utzero < z))
{
value = !up * 1;
return value;
}
y = 0.5 * z * z;
if (z <= con)
{
value = 0.5 - z * (p - q * y
/ (y + a1 + b1
/ (y + a2 + b2
/ (y + a3))));
}
else
{
value = r * Math.exp(-y)
/ (z + c1 + d1
/ (z + c2 + d2
/ (z + c3 + d3
/ (z + c4 + d4
/ (z + c5 + d5
/ (z + c6))))));
}
if (!up)
value = 1 - value;
return value;
}
function NDistJS(x, mean, stdev, cumulative)
{
return cumulative
? _getNDistCDF(x, mean, stdev)
: _getNDistPDF(x, mean, stdev);
}
This gives you a function NDistJS that takes the exact same parameters as NORMDIST.
The PDF is 100% accurate to the Sheets formula.
The CDF is 99.9999992% accurate to the Sheets formula for (x=1, m=0, s=1).

Javascript Maths Node Red Thermistor Function

have node-red running with arduino analogue output through serial to pi, where I'm collecting thermistor data as a msg payload on change.
Trying to turn the Arduino signal into a Temperature - it's the most common 10K enamelised thermistor that adafruit sell. So quite useful code.
The issue is that I am a total noob at JS.
Here's my code so far - using a function node - and trying to replicate the steinhart equation (https://learn.adafruit.com/thermistor/using-a-thermistor)
var input = { payload: msg.payload };
var R0 = 10000;
var R = R0 / ((1023 / input)-1);
var T0 = 273 + 25;
var B = 3950;
var T = 1 / ( (1/T0) + (1/B) * Math.log(R/R0) );
return T;
i am not sure whether will msg.payload will return number in an actual datatype "Number" meaning or a string that will be a numeric, but something like this should take care of any anomalies when trying to divide strings
var numInput = Number(msg.payload);
var R0 = 10000;
var R = R0 / ((1023 / input)-1);
var T0 = 273 + 25;
var B = 3950;
var T = 1 / ( (1/T0) + (1/B) * Math.log(R/R0) );
return T;
EDIT: this should fix the errors:
var numInput = Number(msg.payload);
var R0 = 10000;
var R = R0 / ((1023 / numInput)-1);
var T0 = 273 + 25;
var B = 3950;
var T = 1 / ( (1/T0) + (1/B) * Math.log(R/R0) );
msg.payload = T;
return msg;

generate 4 digit random number using substring

I am trying to execute below code:
var a = Math.floor(100000 + Math.random() * 900000);
a = a.substring(-2);
I am getting error like undefined is not a function at line 2, but when I try to do alert(a), it has something. What is wrong here?
That's because a is a number, not a string. What you probably want to do is something like this:
var val = Math.floor(1000 + Math.random() * 9000);
console.log(val);
Math.random() will generate a floating point number in the range [0, 1) (this is not a typo, it is standard mathematical notation to show that 1 is excluded from the range).
Multiplying by 9000 results in a range of [0, 9000).
Adding 1000 results in a range of [1000, 10000).
Flooring chops off the decimal value to give you an integer. Note that it does not round.
General Case
If you want to generate an integer in the range [x, y), you can use the following code:
Math.floor(x + (y - x) * Math.random());
This will generate 4-digit random number (0000-9999) using substring:
var seq = (Math.floor(Math.random() * 10000) + 10000).toString().substring(1);
console.log(seq);
I adapted Balajis to make it immutable and functional.
Because this doesn't use math you can use alphanumeric, emojis, very long pins etc
const getRandomPin = (chars, len)=>[...Array(len)].map(
(i)=>chars[Math.floor(Math.random()*chars.length)]
).join('');
//use it like this
getRandomPin('0123456789',4);
$( document ).ready(function() {
var a = Math.floor(100000 + Math.random() * 900000);
a = String(a);
a = a.substring(0,4);
alert( "valor:" +a );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
Your a is a number. To be able to use the substring function, it has to be a string first, try
var a = (Math.floor(100000 + Math.random() * 900000)).toString();
a = a.substring(-2);
You can get 4-digit this way .substring(startIndex, length), which would be in your case .substring(0, 4). To be able to use .substring() you will need to convert a to string by using .toString(). At the end, you can convert the resulting output into integer by using parseInt :
var a = Math.floor(100000 + Math.random() * 900000)
a = a.toString().substring(0, 4);
a = parseInt(a);
alert(a);
https://jsfiddle.net/v7dswkjf/
The problem is that a is a number. You cannot apply substring to a number so you have to convert the number to a string and then apply the function.
DEMO: https://jsfiddle.net/L0dba54m/
var a = Math.floor(100000 + Math.random() * 900000);
a = a.toString();
a = a.substring(-2);
$(document).ready(function() {
var a = Math.floor((Math.random() * 9999) + 999);
a = String(a);
a = a.substring(0, 4);
});
// It Will Generate Random 5 digit Number & Char
const char = '1234567890abcdefghijklmnopqrstuvwxyz'; //Random Generate Every Time From This Given Char
const length = 5;
let randomvalue = '';
for ( let i = 0; i < length; i++) {
const value = Math.floor(Math.random() * char.length);
randomvalue += char.substring(value, value + 1).toUpperCase();
}
console.log(randomvalue);
function getPin() {
let pin = Math.round(Math.random() * 10000);
let pinStr = pin + '';
// make sure that number is 4 digit
if (pinStr.length == 4) {
return pinStr;
} else {
return getPin();
}
}
let number = getPin();
Just pass Length of to number that need to be generated
await this.randomInteger(4);
async randomInteger(number) {
let length = parseInt(number);
let string:string = number.toString();
let min = 1* parseInt( string.padEnd(length,"0") ) ;
let max = parseInt( string.padEnd(length,"9") );
return Math.floor(
Math.random() * (max - min + 1) + min
)
}
I've created this function where you can defined the size of the OTP(One Time Password):
generateOtp = function (size) {
const zeros = '0'.repeat(size - 1);
const x = parseFloat('1' + zeros);
const y = parseFloat('9' + zeros);
const confirmationCode = String(Math.floor(x + Math.random() * y));
return confirmationCode;
}
How to use:
generateOtp(4)
generateOtp(5)
To avoid overflow, you can validate the size parameter to your case.
Numbers don't have substring method. For example:
let txt = "123456"; // Works, Cause that's a string.
let num = 123456; // Won't Work, Cause that's a number..
// let res = txt.substring(0, 3); // Works: 123
let res = num.substring(0, 3); // Throws Uncaught TypeError.
console.log(res); // Error
For Generating random 4 digit number, you can utilize Math.random()
For Example:
let randNum = (1000 + Math.random() * 9000).toFixed(0);
console.log(randNum);
This is quite simple
const arr = ["one", "Two", "Three"]
const randomNum = arr[Math.floor(Math.random() * arr.length)];
export const createOtp = (): number => {
Number(Math.floor(1000 + Math.random() * 9000).toString());
}

decimal value addition not working in javascript

function sum() {
a = Number(document.getElementById("rate_ts").value);
b = Number(document.getElementById("discount").value);
c = a - (Number(a) * Number(b) / 100);
d = Number(document.getElementById("ocharge").value) + c + Number(document.getElementById("pay_amt").value);
tax = (Number(a) * Number(12.36) / 100);
e = tax + d;
document.getElementById("net_amt").value = e;
}
this code is not working right......i want to add tax and for that i have given 12.36 but it is not returning anything..plz help
parseFloat()
Summary
The parseFloat() function parses a string argument and returns a
floating point number.
$('#three').click(function (e) {
a = parseFloat(document.getElementById("rate_ts").value);
b = parseFloat(document.getElementById("discount").value);
console.log(a+' | '+b);
});
WORKING DEMO
Try This,
function sum() {
a = parseFloat(document.getElementById("rate_ts").value);
b = parseFloat(document.getElementById("discount").value);
c = a - (a * b / 100);
d = parseFloat(document.getElementById("ocharge").value) + c + parseFloat(document.getElementById("pay_amt").value);
tax = a * 12.36 / 100;
e = tax + d;
document.getElementById("net_amt").value = e.toFixed(2);
}
If you want only two decimal point value then use number.toFixed(2)
Working Example

Javascript Split String Without Separator

Basically, I have a string of unknown numbers (determined by user input + my own math), and I need to split this string into 3 parts.
For example, I may have "1273498". I need to split it at the two characters, and the 3rd and 4th from the RIGHT, like so:
127
34
98
Another example: 1234567890 would need to be:
123456
78
90
Currently, I am accomplishing it this way:
// get first input box value
var depositgold = document.getElementById('v-gold').value;
// set it to 0 if it's empty
if(depositgold == null || depositgold == '')
depositgold = 0;
// second input box value
var depositsilver = document.getElementById('v-silver').value;
if(depositsilver == null || depositsilver == '')
depositsilver = 0;
// third input box value
var depositcopper = document.getElementById('v-copper').value;
if(depositcopper == null || depositcopper == '')
depositcopper = 0;
// combine the 3 input box values (adding dec to make split easier)
var depositnums = depositgold + '.' + depositsilver + depositcopper;
// do some math on our new value, then split it at out dec
var deposit12 = (0.15 * depositnums).toFixed(4).split(".");
// split the last part of the above split into 4 characters
var result12 = deposit12[1].split("", 3);
// keep the first part of out dec split
var deposit12gold = deposit12[0];
// combine the second part split results into paired numbers
var deposit12silver = result12[0] + result12[1];
var deposit12copper = result12[2] + result12[3];
// repeat the above process
var deposit24 = (0.30 * depositnums).toFixed(4).split(".");
var result24 = deposit24[1].split("", 3);
var deposit24gold = deposit24[0];
var deposit24silver = result24[0] + result24[1];
var deposit24copper = result24[2] + result24[3];
var deposit48 = (0.60 * depositnums).toFixed(4).split(".");
var result48 = deposit48[1].split("", 3);
var deposit48gold = deposit48[0];
var deposit48silver = result48[0] + result48[1];
var deposit48copper = result48[2] + result48[3];
I know there must be a much better (and more sane) way of accomplishing the above - I need to do it several more times for this project, and I'm certainly not looking forward to continuing to do it this way.
I am new to JS and programming, so laugh away, just try not to laugh too hard ;)
Try something along these lines:
var str = "123412341";
var matches = str.match(/(.+?)?(.{2})?(.{2})?$/);
// matches[1] = 12341
// matches[2] = 23
// matches[3] = 41
You may want to modify the RegEx depending on your input, currently all groups are optional.
Just use the substring method
var number = 123456789;
var one = number.substring( 0, number.length - 4 );
var two = number.substring( number.length -4, number.length - 2);
var three = number.substring( number.length - 2 );
Use the substr() method for this:
var L = mystring.length
var part1 = mystring.substr(0,L-4);
var part2 = mystring.substr(L-4,2);
var part3 = mystring.substr(L-2,2);
('1234'+'56'+'78').match(/(\d*)(\d\d)(\d\d)/)
["12345678", "1234", "56", "78"]
var number = 1234567890;
number = number.toString();
var a = number.substr(0, number.length - 4),
b = number.substr(-2),
c = number.substr(number.length - 4, 2);
console.log(a, b, c);
jsFiddle.
Output
123456 90 78
here is a function i made:
/**
* #param num A number to split like 382203849238
* #return Returns an array of size 3, where index 0 = 38220384, index 1 = 92, index 2 = 38 based on the example above
*/
function splitNumbers(num) {
var num = (typeof num == 'string' || typeof num == 'String') ? parseInt(num) : num,
rem = num % 10000;
return [Math.floor(num / 10000), Math.floor(rem / 100), rem % 100];
}
// Function to parse code in 3 parts
function parse_code_Split (code)
{
var len = code.length;
var divisor = (len / 3) >> 0; // get whole number
console.log(divisor);
var stringReg = "";
var regexp = ".{1," + divisor + "}";
try{
stringReg = new RegExp(regexp,"g");
}catch(Error){
window.console.log(Error.message);
}
codeSplit = code.match(stringReg);
// window.console.log(" codeSplit[0] " + codeSplit[0]);
// window.console.log(" codeSplit[1] " + codeSplit[1]);
// window.console.log(" codeSplit[2] " + codeSplit[2]);
// window.console.log(" codeSplit[3] " + codeSplit[3]); // remainder
return codeSplit;
}

Categories