I am currently learning JS and when I do some practice, I find some issues I am unclear on data type in Javascript. I understand that JS do NOT require specific type indication, it will automatically do the type conversion whenever possible. However, I suffer one problem when I do NOT do type conversion which is as follows:
var sum = 0;
function totalSum (a) {
if (a == 0) {
return sum;
}
else {
sum += a;
return totalSum(--a);
}
}
var i = prompt("Give me an integer");
// var num = parseInt(i);
alert("Total sum from 1 to " + i + " = " + totalSum(i));
// alert("Total sum from 1 to " + i + " = " + totalSum(num));
I notice that the code works perfectly if I change the data type from string to int using parseInt function, just as the comment in the code does. BUT when I do NOT do the type conversion, things are getting strange, and I get a final result of 054321, if I input the prompt value as 5. AND in a similar way, input of 3, gets 0321 and so on.
Why is it the case? Can someone explain to me why the totalSum will be such a number? Isn't javascript will automatically helps me to turn it into integer, in order for it to work in the function, totalSum?
The sample code can also be viewed in http://jsfiddle.net/hphchan/66ghktd2/.
Thanks.
I will try to decompose what's happening in the totalSum method.
First the method totalSum is called with a string as parameter, like doing totalSum("5");
Then sum += a; (sum = 0 + "5" : sum = "05") (note that sum become a string now)
then return totalSum(--a);, --a is converting the value of a to a number and decrement it's value. so like calling return totalSum(4);
Then sum += a (sum = "05" + 4 : sum = "054") ...
See the documentation of window.prompt: (emphasis mine)
result is a string containing the text entered by the user, or the value null.
Related
I have just started learning Javascript. I am doing the course in Viope World. I need to get two different numbers, but each time, I get the same number for the num and exponent variables, while the function calcPower is correct. I don't understand how to get different inputs in the function fetchValue() without having HTML for this task. I have tried using the method Document.querySelector() and other things which shouldn't be complicated for such an exercise.
These are the requirements:
Fill in the missing functions fetchValue(id) and calcPower(base, exponent). The function fetchValue(id) looks for a HTML text input element and returns its value. The function calcPower(base, exponent) has to calculate and return a number based on the values passed to it. Note that all of the printing happens within the pre-made section of the program.
This is the part of the code I can't change:
function calcFunc(){
var num = fetchValue("num");
var exponent = fetchValue("exponent");
console.log("The number " + num + "to the power of " + exponent + " is:");
console.log(calcPower(num, exponent));
}
My code:
function fetchValue(id){
let val = document.querySelector("input").value;
return val;
}
function calcPower(base, exponent){
var result = 1;
for(var counter=0; counter<exponent;counter++){
result*=base;
}
return result;
}
querySelector returns a reference to the first element of the given selector. See https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector. It is not the obvious way to fetch your values given that your function is set up to handle element ids.
Instead, individual elements with unique id can be referenced using document.getElementById("elementID") and you want the .value property of the element. See https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById.
To input values, the html needs some sort of input, you could use text or number inputs (both return strings, but the number input restricts entries to digits). The markup for these would be something like:
Number: <input type="number" id="inputValue"></input><br>
Exponent: <input type="number" id="inputExponent"></input>
Note the use of ids as attributes of the elements.
Javascript is a loosely typed language, meaning strict definition of variable types is not needed. This means that JS can make sensible calculations from 2*2 or "2"*"2" (both are calculated to be 4). However, it is good practice to formally convert string digits to numbers when you intend using them for calculations (not least because JS interprets "2"+"2" as "22" because + is both an arithmetic addition operator and a string concatenation operator so if you give it strings, JS assumes you want to concatenate them).
So, the fetchValue function could include the use of parseInt(string) to convert the input string values to numbers.
These principles are combined in the following working snippet to illustrate the approach:
function calcFunc(){
let num = fetchValue("inputValue");
let exponent = fetchValue("inputExponent");
console.log("The number " + num + " to the power of " + exponent + " is:");
console.log(calcPower(num, exponent));
}
function fetchValue(id){
return parseInt(document.getElementById(id).value);
}
function calcPower(base, exponent){
let result = 1;
for(let counter=0; counter<exponent;counter++){
result*=base;
}
return result;
}
input {
width: 3em;
}
Number: <input type="number" id="inputValue"></input><br>
Exponent: <input type="number" id="inputExponent"></input>
<p>
<button onclick="calcFunc()">process</button>
I hope this helps, If the exponent is negative, the result is 1 / (base^exponent). For example: 2^(-4) = 1 / (2^4) = 1 / 2 / 2 / 2 / 2. meaning the number 2 to the power of -4 is: 0.0625 and not 1
Math.abs is important here...
function fetchValue(id){
return document.getElementById(id).value;
}
function calcPower(base, exponent){
if (exponent == 0){
return 1;
}
else if(exponent < 0){
exponent = Math.abs(exponent);
return (1 / calcPower(base, exponent));
}
else if(exponent > 0){
return base * (calcPower(base,exponent - 1));
}
};
I'm attempting to update a value in an object and set it to the current value + another number. So for instance, if an object's value is 5, I want it to update like this: object key : current value (5) + 7
container[response["id"]]["quantity"] += quantity;
console.log(container[response["id"]].attr("quantity"));
This is what I'm currently attempting.. I end up with 57 instead of 12.
Any ideas?
You get as a string and + with strings concatenate them. First parse to the number using parseInt() or parseFloat() than add.
let number = parseInt(container[response["id"]]["quantity"]);
number += quantity;
container[response["id"]]["quantity"] = number;
The issue is, the value return by response["id"]]["quantity"] is a string. And when you try to add a number using + to a string, then it will concatenate it, something like 5 + 7 is 57. To deal with this, you have to parse the number to Int or to Float by using parseInt() or parseFloat(). Ex:
let num = parseInt(container[response["id"]]["quantity"]);
num += quantity;
container[response["id"]]["quantity"] = num;
I am a beginner in JavaScript. Our teacher asked us to write a program to add two numbers using function add(). The question is shown as follows.
However, when I use my code to add the two numbers. The result is not a number.
<html>
<head> <title> Third example </title>
<script type="text/javascript">
function sum (x,y)
{ num1=parseInt(x);
num2=parseInt(y);
return (num1+num2);}
var input1 = window.prompt("Enter a number: ", 0);
var input2 = window.prompt("Enter another number: ", 0);
var input3 = window.prompt("Enter another number: ", 0);
var value1 = parseFloat(input1 + input2);
var value3 = parseFloat(input3);
var sum = sum(value1 + value3);
document.writeln("<h1> First number: " + value1 + "</h1>");
document.writeln("<h1> Second number: " + value3 + "</h1>");
document.writeln("<h1> Sum: " + sum + "</h1>");
</script>
<head>
<body></body> </html>
Why the sum is not a number?
You have to add parseFloat() separately for input1 and input2 when you calculate the sum for value1. Another change is the var sum = sum1(value1 , value3); instead of var sum = sum1(value1 + value3); which makes the parameter y of sum(x,y) as undefined.
var input1 = window.prompt("Enter a number: ", 0);
var input2 = window.prompt("Enter another number: ", 0);
var input3 = window.prompt("Enter another number: ", 0);
var value1 = parseFloat(input1) + parseFloat(input2);
var value3 = parseFloat(input3);
var sum = sum1(value1 , value3);
document.writeln("<h1> First number: " + value1 + "</h1>");
document.writeln("<h1> Second number: " + value3 + "</h1>");
document.writeln("<h1> Sum: " + sum + "</h1>");
function sum1 (x,y)
{
return (x+y);
}
Also, as Adriani6 mentioned you don't need to parseFloat again inside sum1 as you assign a parsed float already to value1 and value3
Although a bit dirty, this works:
var amount = 58.02;
var total = '£' + (amount*1 + 177);
...gives the the expected answer of £217.73
Enclosing within brackets forces 'amount' to be a number. However...
var amount = 40.73;
var total = '£' + (amount*1 + 177.82);
gives a really silly answer of £218.54999999999998 (!)
[ Edited 26th January - following part in italics kept for reference...
This is only true if the (correct) decimal part of the answer is .55 or .65 Bug in Javascript???? (It's the same in Firefox and Chrome.)
So some more manipulation is required to be absolutely certain: multiplication, integerising and subsequent division by 100...
var amount = 40.73;
document.write('Total is: £' + parseInt(amount*100 + 17782) / 100);
.. gives the correct answer of 'Total is: £218.55' ]
Edit: Better solution found later uses toFixed() :-
var amount = 40.73;
var total = 'Total is: £' + (amount* + 177.82).toFixed(2);
.. also gives the correct answer of 'Total is: £218.55'
Soooooo -
1) You need to enclose the numbers you want to add within brackets if the sum will be part of a string;
2) Multiplying each 'number' by one forces the result to be a number - so (input1*1 + input2*1) is forced to be the arithmetic sum. This is necessary in the original questioner's script, but multiplying by one isn't needed in my example;
3) To ensure you don't get a silly answer, append .toFixed(n) to the bracketed expression - where n is the number of decimal places.
Utterly tedious (still)....
(and) Much better to use PHP if you can!
The error you're seeing is here:
sum(value1 + value3)
Your sum function expects the arguments separately and will internally perform the addition, but you're adding them in-line before sending them to the function. Since only one value is sent to sum(), its second argument is undefined and therefore "not a number". Simply separate the values:
sum(value1, value3)
The other error that you may not have noticed yet is here:
parseFloat(input1 + input2)
If you enter 1 and 2 for example, the result of this will be 12. This is because you're "adding" (concatenating) the strings before converting them to a numeric value. Convert them first, then add them. Something like this:
var value1 = parseFloat(input1) + parseFloat(input2);
Aside from that the code can probably be cleaned up a bit more, such as not needing all of the parsing you're doing. (Once something is parsed to a numeric value, it doesn't need to be parsed to a numeric value again.) You'd also do well to look into setting values to elements on the page instead of using things like document.writeln(), but that could be a lesson for another day.
Because in Javascript, the + operator is overloaded, i.e., has multiple meanings depending on the arguments you give it. The + means concatenation for strings and addition for "numbers" (for different types of numbers).
You can use an add function that takes and ads as many parameters as you need:
function add() {
// Create an array from the functions arguments object
// then sum the array members using reduce
var sum = Array.from(arguments).reduce(function(a, b) {
return a + b;
});
console.log(sum);
}
// You can now add as many numbers as you like
// just by passing them to the function
add(2, 5);
add(2, 3, 5);
I'm trying to make a simple addition tool to add 2 values together, I'm just having a little trouble with the NaN checking... would like to print "Please insert numbers only" if either A or B, or both are NaN.
function getTotal() {
var a = parseInt(document.addBoxes.boxA.value);
var b = parseInt(document.addBoxes.boxB.value);
if (total != NaN) {
total = a+b;
document.getElementById("total").innerHTML = "The sum is " + total + ".";
}
else if (a === NaN || b === NaN){
document.getElementById("total").innerHTML = "Please insert numbers only.";
}
else if (a === NaN && b === NaN){
document.getElementById("total").innerHTML = "Please insert numbers only.";
}
};
Also, if there is a performance-friendly way to do this, or a better method.
Thanks!
Checking each individual value for NaN is not required.
function getTotal() {
var a = parseInt(document.addBoxes.boxA.value);
var b = parseInt(document.addBoxes.boxB.value);
var total = a + b;
if (!isNaN(total)) {
document.getElementById("total").innerHTML = "The sum is " + total + ".";
} else {
document.getElementById("total").innerHTML = "Please insert numbers only.";
}
}
Several problems in your code.
Line 4: if (total != NaN) {
total hasn't been defined yet. You should define it in a var beforehand if you don't want to leak globals.
var total = a + b;
Also, NaN will never equal itself so this kind of equality is dangerous. Either use the built-in isNaN() function to check for NaN or (since you mentioned performance-friendly) you can skip the function invocation and use:
if (total !== total) {
Since NaN is the only thing in javascript that doesn't equal itself. Notice I'm using a strict not-equals, we don't want any coercion. This might be a bit too abstract and people who look at the code later (including yourself) might have forgotten this unique property of NaN so I'd prefix this conditional with a comment and perhaps a link to the MDN - Necessity of isNaN page.
Your code might end up looking something like simonzack's answer.
i would like to format decimal values to specific format as like
1.23 should be shown as 0001.23 using javascript. is there any specific functions like toPrecision(), tofixed() in javascript to handle these kind of formatting or any pointers to go ahead with any solutions?
here preceeding decimal is dynamic one.
for example :
i have 2 values :
first value : 99.4545
second value : 100.32
in this second value has higher length (3)before decimal and first value has higher length after decimal(4). so subtracted result(0.8655) of this should be formatted as ###.#### (000.8685)
thank you
Just make a function that does what you want it to. Here is an example you can expand on if you want.
function pad(num, padSize){
var numString = "" + num.split('.')[0];
if(num.length < padSize){
var numZeroes = padSize-num.length;
var zeroes = "";
while(numZeroes){zeroes += "0"; numZeroes--;}
return zeroes + num;
}else return num;
}
if you want to lpad some 0 onto 1.23 you can do the following
var value = 1.23
value = ("0000000"+ value).slice(-7);
Change the -7 to be whatever you want the total string length including the decimal point to be.
Added after question edit
The above should handle your question pre-edit but for the rest of it you'll need something like this.
var formatNum = function (num, preLen, postLen) {
var value = num.split("."),
padstring = "0";
padLen = (preLen > postLen)?preLen:postLen;
for (i = 0; i < padLen; i++) {
padstring += padstring;
}
if (typeof(value[1]) === "undefined") {
value[1] = "0";
}
return ((padstring + value[0]).slice(-preLen)+ "." + (value[1] + padstring).substring(0,postLen));
}
This takes the number you want formatted and the lengths you want each string to be on either side of the '.'. It also handles the case of an integer.
If you want it to output any other cases such as returning an integer, you'll have to add that in.
Try to use a string, like "000" + some value