What is wrong with my code?? Everything except the subtraction works. It just returns NaN. I am new to javascript so i might have written my code poorly.
// Variables
var count = prompt("Choose an arithmetic method: \n1. Addition \n2. Subtraktion\n3. Multiplikation\n4. Division");
var x = parseInt(prompt("Enter your first number", "0"));
var y = parseInt(prompt("Enter your second number", "0"));
var z = +x + +y;
// Switch function with 4 cases
switch(count) {
case '1':
alert("Answer: " + z);
break;
case '2':
alert("Answer: " + x - y);
break;
case '3':
alert("Answer: " + x * y);
break;
case '4':
alert("Answer: " + x / y);
break;
}
You need to group the operations in parentheses, for instance alert("Answer: " + (x - y)); (and the same for the others). Otherwise JavaScript runs "Answer: " + x first, resulting in a string.
Also, always specify the radix (you want 10) for parseInt: parseInt(input, 10), otherwise some engines get confused with octal numbers.
Your trouble is here:
alert("Answer: " + x - y);
Due to how the association of operators work, it works as if you had written this:
alert(("Answer: " + x) - y);
You need to write it like this:
alert("Answer: " + (x - y));
Snippet here:
// Variables
var count = prompt("Choose an arithmetic method: \n1. Addition \n2. Subtraktion\n3. Multiplikation\n4. Division");
var x = parseInt(prompt("Enter your first number", "0"));
var y = parseInt(prompt("Enter your second number", "0"));
var z = +x + +y;
// Switch function with 4 cases
switch (count) {
case '1':
alert("Answer: " + z);
break;
case '2':
alert("Answer: " + (x - y));
break;
case '3':
alert("Answer: " + x * y);
break;
case '4':
alert("Answer: " + x / y);
break;
}
Wrap your subtraction in parentheses: (x - y). You would get an unexpected result from the addition, too, if you put x + y there instead of z.
What's happening is operator precedence. Multiplication and division are higher precedence than addition, so they get done first - before the implicit conversion to string for concatenation.
With subtraction, '+' and '-' are equal in precedence and so get done in order from left to right. So the concat takes place before the math, which leaves you attempting to subtract y from a string (which doesn't work, and so...NaN).
With addition, it would simply concatenate the two numbers onto the string.
Related
Im looping over a collection of coordinate values and doing math on the coordinates to see if the calculated values are in a hashmap. if they are in the hash map then I want to run an additional function. since I had multiple cases I wanted to check for each coord in the collection, I figured a switch statement would be cool to use to replace my if statements so all my checks could be visually and logically grouped. When I replaced my if statements with a switch, my code returned bad results. When I debugged, I realized the switch statements would sometimes execute even when the case was false(I added console.logs to output the result of the same switch condition and it would print false, but should only run when true). Here is a small example:
var idm = {0:1, 3:1, 9:1, 10:1, 11:1, 12:1, 20:1, 21:1, 23:1}
var findNeighbors = function(b) {
var u,d,l,r,lRow,rRow;
var currentBuilding = parseInt(b);
var currRow = Math.floor(currentBuilding/column);
//remove value from map so we dont recount it.
delete idm[currentBuilding];
u = currentBuilding - column;
d = currentBuilding + column;
l = currentBuilding - 1;
lRow = Math.floor(l/column);
r = currentBuilding + 1;
rRow = Math.floor(r/column);
console.log("current idx:" + currentBuilding);
console.log("u:" + u + ", d:" + d + ", l:" + l + " r:" + r);
// debugger;
switch(true) {
case (idm.hasOwnProperty(u) === true):
console.log((idm.hasOwnProperty(u)));
console.log("map has " + currentBuilding + " -> u: " + u);
findNeighbors(u);
case (idm.hasOwnProperty(d) === true):
console.log((idm.hasOwnProperty(d)));
console.log("map has " + currentBuilding + " -> d: " + d);
findNeighbors(d);
case (lRow === currRow && idm.hasOwnProperty(l) === true):
console.log((lRow === currRow && idm.hasOwnProperty(l)));
console.log("map has " + currentBuilding + " -> l: " + l);
findNeighbors(l);
case (rRow === currRow && idm.hasOwnProperty(r) === true):
console.log((rRow === currRow && idm.hasOwnProperty(r)))
console.log("map has " + currentBuilding + " -> r: " + u);
findNeighbors(r);
}
console.log("---------------------------");
}
I figured a switch statement would be cool to use to replace my if statements so all my checks could be visually and logically grouped.
Well, write code that works not code that looks cool. You were forgetting break statements, so the execution flow fell through - without evaluating the other case expressions after the first one matched. Btw switching on a constant is a horrible (uncool) practice.
Use standard if/else instead.
I'm new to JavaScript, and are fooling around to really understand the basics. Now I try to make a calculator. A very basic one, that can add, subrtact, devide and multiply. I've gotten it to work with this code(showing multiply only:
var multiply = function () {
var numbers = prompt("How many numbers do you want to multiply?","At least 2, max 4");
numbers = Number(numbers);
switch (numbers){
case 2:
num1 = prompt("Your first number: ");
num2 = prompt("Your second number: ");
ans = Number(num1) * Number(num2);
alert(num1 + " * " + num2 + " = " + ans);
break;
case 3:
num1 = Number(prompt("Your first number: "));
num2 = Number(prompt("Your second number: "));
num3 = Number(prompt("Your third number: "));
ans = Number(num1) * Number(num2) * Number(num3);
alert(num1 + " * " + num2 + " * " + num3 + " = " + ans);
break;
case 4:
num1 = Number(prompt("Your first number: "));
num2 = Number(prompt("Your second number: "));
num3 = Number(prompt("Your third number: "));
num4 = Number(prompt("Your fourth number: "));
ans = Number(num1) * Number(num2) * Number(num3) * Number(num4);
alert(num1 + " * " + num2 + " * " + num3 + " * " + num4 + " = " + ans);
break;
default:
alert("Not valid");
break;
}
};
multiply();
My problem is that I'm very limited when it comes to how many numbers the user can multiply. Making a switch case for each possible quantity is going to take a while, so I thought of this:
var multiply = function () {
var numbers = [];
var ans = 0;
var times = prompt("How many numbers do you want to multiply?");
for(var i = 0; i<times; i++){
Number(numbers.push(prompt("Please, enter one of your numbers")));
}
alert(ans);
};
multiply();
So, my question is: How can I get "ans" to be equal to each element of my array "numbers" multiplied with eachother?
You can use reduce function:
[1, 2, 3, 4].reduce(function(a, b) {
return a * b;
}); // it return 24
Btw. in your loop you should push to array in this way:
for(var i = 0; i<times; i++){
numbers.push(Number(prompt("Please, enter one of your numbers")));
}
As stated in other answers you can use the Array.reduce method. But rather than rolling your own multiplication function you can also use the native Math.imul method:
var numbers = [1, 2, 3, 4];
var ans = numbers.reduce(Math.imul);
console.log(ans);
If I understand you properly you want something like multiply([1, 2, 3, 4]) === 24 ?
Then you can use https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
You could just keep asking for a number and show the intermediate result at the same time. The user can exit with escape:
var multiply = function () {
var s, ans = 1;
while (s = prompt('Current product is ' + ans +
'. Enter next factor to multiply with, or hit escape to exit')) {
ans *= Number(s);
}
}
multiply();
Reduce is probably the right answer, but to give you a more complete understanding of what it's actually doing, take a look at this. This is how I would manually do basically the same thing, adding a few guards to make it more safe.
//This is an enum. It's basically a cleaner and more
//scalable way to define constants. Here I'm using an
//integer to represent each of the four operations
var OPERATIONS = {
'ADD': 1,
'SUBTRACT': 2,
'MULTIPLY': 3,
'DIVIDE': 4
};
function calc (operation, values)
{
if (!operation || !values || values.length < 2)
{
//The inputs aren't valid, so throw some kind of error
}
//This will be used in all of our cases, so
//we define it at a larger scope
var result;
switch (operation)
{
case OPERATIONS.MULTIPLY:
//Extracts the first value and stores it
result = values.shift ();
//Iterate through the remaining values.
//Remember that the first value is no
//longer in the set
values.forEach (function (value, index)
{
//*= is a unary operator which multiplies a value by
//the operand, and then stores it back in itself.
//This is equivalent to result = result * value.
result *= value;
});
break;
//Create cases for ADD, SUBTRACT, and DIVIDE
}
return result;
}
//Test cases
console.log (calc (OPERATIONS.ADD, [1, 1]); //Prints 2
console.log (calc (OPERATIONS.SUBTRACT, [10, 1, 1]); //Prints 8
console.log (calc (OPERATIONS.MULTIPLY, [1, 2, 3, 4]); //Prints 24
console.log (calc (OPERATIONS.ADD, [calc (OPERATIONS.MULTIPLY, [5, 5], 3, 100]); //Prints 128
You can make it a bit more generalised if you want doing something like this...
function calc2 (operations, values)
{
//You need one more value than operation here
if (!operations || !values || values.length < 2 || (values.length - operations.length !== 1))
{
//The inputs aren't valid, so throw some kind of error
}
var result = values.shift ();
while (values.length)
{
switch (operations[0])
{
case OPERATIONS.ADD:
result += values[0]
break;
case OPERATIONS.SUBTRACT:
result -= values[0]
break;
case OPERATIONS.MULTIPLY:
result *= values[0]
break;
case OPERATIONS.DIVIDE:
result /= values[0]
break;
default:
//Something has gone horribly wrong. Thrown an error
}
//Work your way down the array by continually
//removing the first value
values.shift ();
operations.shift ();
}
//Note that this method solves the equation linerally;
//BEDMAS (or PEMDAS, depending on where you're from)
//is not honoured.
return result;
}
//Test cases
console.log (calc ([OPERATIONS.ADD], [1, 1])); //Prints 2
console.log (calc ([OPERATIONS.ADD, OPERATIONS.ADD], [1, 2, 3])); //Prints 6
console.log (calc ([OPERATIONS.ADD, OPERATIONS.ADD, OPERATIONS.DIVIDE], [6, 7, 5, 3])); //Prints 6
This second function would be used by storing the inputs and the operations one by one. So you get something like 6 + 7 + 5 / 3 =, and then you break it into its individual components to do the calculation.
The general methodology here is that you want to get a base value, and then iterate on top of it to get your final result. In the first case, this means mutating the value with the same operation for every value. In the second case you tell it the type of mutation that you'd like to perform at every step instead of at the beginning.
If you want to generalise this to used BEDMAS or have more complex functionality, you would probably have to create a tree structure where each node represents an operation and its respective operands, and to get your result you would simply traverse the tree.
e.g. PLUS(PLUS(DIVIDE(5, 3), 7), 6)
I made a simple calculator in javascript but the + button doesn't work and it just show the numbers near together
Here is my code:
<script>
function calc(operator) {
var x = document.getElementById("inp1").value;
var y = document.getElementById("inp2").value;
var z = 0;
switch (operator) {
case "+":
z = x + y;
break;
case "-":
z = x - y;
break;
case "*":
z = x * y;
break;
case "/":
z = x / y;
break;
}
document.getElementById("result").innerHTML=z;
}
</script>
You may use like this:
z= +x + +y; // + is prefixed to convert input into number
The x and y variables contain strings. Parse them to numbers:
var x = parseFloat(document.getElementById("inp1").value);
var y = parseFloat(document.getElementById("inp2").value);
It happens to work for the other operators, because there are no subtraction, multiplication or division for strings, it figures out that it has to convert the strings to numbers.
var x=document.getElementById("inp1").value;
var y=document.getElementById("inp2").value;
return you values in those text boxes as strings.
When you use + operator on strings, it will concatenate the values. If you use the same operator on numbers, it will add the values.
You will need to parse the text box values into integer using the parseInt function using one of the following ways.
var x=parseInt(document.getElementById("inp1").value);
var y=parseInt(document.getElementById("inp2").value);
and then do z=x+y; I would recommend this because all the operations, not just addition, will be perfomed on the integers.
or simply change z=z+y; to look like z = parseInt(x) + parseInt(y);
A quick way to convert a string to a number is to use the unary + operator.
z = +x + +y
or
z = parseInt(x) + parseInt(y);
var x = parseInt(document.getElementById("inp1").value);
this converts your "string" number to integer, also you can use parseFloat() if you have float numbers
You may use like this:
var x = document.getElementById("inp1").value*1;
var y = document.getElementById("inp2").value*1;
x in this moment is number!!
More clean for me!!!
Just wondering if anyone can work out why I keep getting for eg. 3+3=33 and not 6.
The rest of the coding works fine for the divide and times its the addition that keeps stuffing up and wont come up with the correct answer.. please help if you can.
here is my code:
<html>
<head>
<title>Practical Task 8 </title>
</head>
<body>
<button onclick="myFunction()">Press & Enter First Digit & Second Digit</button>
<script type="TEXT/JavaScript">
function myFunction()
{
var x=prompt("Please enter first number","0");
var y=prompt("Please enter second number","0");
var sum = x;
var sum2 = y;
var n = (x * y);
var n2 = (x / y);
var n3 = (x + y);
document.write(sum + " + " + sum2 + " = " + n3);
document.write("<BR>" + sum + " * " + sum2 + " = " + n);
document.write("<BR>" + sum + " / " + sum2 + " = " + n2);
}
</script>
</body>
</html>
You're performing string concatenation, not integer addition.
Use parseInt first:
x = parseInt( x, 10 );
y = parseInt( y, 10 );
MDN recommends always specifying the radix (the 10 part) to avoid problems, such as if a user prepends a number with 0 (where it'll be parsed as octal), or if different browsers have a different default radix (wtf, I know!).
You have to do this because the output of prompt is always a string, even if it's a number (e.g. "10" or "0123"), you need to tell JavaScript to interpret the data as a number (use parseInt if it's an integer (a whole number), or use parseFloat if you'll accept numbers with decimal places). Confusingly the + operator works for both string and number types, where it performs either concatenation (i.e. joining strings together like glue) or addition depending on the type of its operands.
Because your code is adding strings.
User input is always string.
You need to parseInt(x, 10) and parseInt(y, 10) to parse the string value into int base 10.
Just say I have a string like this: '1 + 2 + 3 * 4'
Is it possible to calculate it from left to right (sequentially? Linearly?) so that it equals 24 and not 15 ?
I don't know what the string is before-hand, so it might be '1 + 2' or it might be '1 + 7 * 11 - 18 / 32 * 155'
Assuming you start with a number and spaces only (and always) occur between numbers and operators, you could split the string and pass it through an object of defined operators
var num_eval = (function () {
var ops = {
'+': function (x, y) {return x + y},
'-': function (x, y) {return x - y},
'*': function (x, y) {return x * y},
'/': function (x, y) {return x / y}
// etc..
};
return function (str_command) {
var str_arr = str_command.split(' '),
lhs = +str_arr[0], i = 1; // + to cast Number
for (; i < str_arr.length; i = i + 2) {
lhs = ops[str_arr[i]](lhs, +str_arr[i+1]); // + to cast Number
}
return lhs;
};
}());
num_eval('1 + 2 + 3 * 4'); // 24
num_eval('1 + 7 * 11 - 18 / 32 * 155'); // 339.0625
If you want to be a little more relaxed about string formatting, then you could use the following RegExp.
str_arr = str_command.match(/([\+\-\*\/]|[\d]*[\.e]?[\d]+)/g)
The loop still assumes an odd length array, starting with a Number (as String).
A one-liner:
result = str.match(/\D*\d+/g).reduce(function(r, e) { return eval(r + e) })
Usually you just insert parenthesis.
But if by some reason you cannot do that, you can split the string by operators and then evaluate previous_part + next_part for each of them.
Here's a super simple example:
var string_to_calculate = '1 + 2 + 3 * 4'
var parts = string_to_calculate.split(' ');
var result = parts[0];
for (var i = 1; i < parts.length - 1; i += 2) {
result = eval(result + parts[i] + parts[i + 1]);
}
alert(result);