Getting NaN after doing an operation in my calculator

html-css
javascript

#1

Hello! :smiley: I was doing one of my projects, as to begin with, consisting in HTML, CSS and JavaScript all together. I have done a lot of progress in 3 days but now I have faced a bug i can't seem to find the solution to. The relevant part of my code where the bug might be is the next:

HTML part:

<li><input type="button" class="button" value="4" onclick='numero(4)'></li>
<li><input type="button" class="button" value="5" onclick='numero(5)'></li>
<li><input id="comma" type="button" class="sbutton" value="," onclick='decimal_true()'></li>
<li><input type="button" class="button" value="+" onclick='operate("+")'></li>
<li id="output">0</li>

JavaScript

var operation = [0,' ', 0, 0];
var answer;
var decimal = false;
var decimal_true = function () {
	decimal=true;
}
var decimal_two = false;
var decimal_two_true = function () {
	decimal_two = true;
}
var operate = function(y) {
	operation[2] = 0;
	operation[1] = y;
	operation.reverse();
	document.getElementById("output").innerHTML = operation[0];
	decimal=false;
	document.getElementById("comma").removeEventListener("click", decimal_true);
	document.getElementById("comma").addEventListener("click", decimal_two_true);
};

JavaScript part returning NaN:

	if(decimal) {
		operation[2]= operation[2].toString();
		var l = operation[2].length;
	 	var y = Math.pow(10,l);
		operation[0]-=(operation[2]/y);
		operation[2]*=10;
		operation[2]+=x;
		operation[2]= operation[2].toString();
		l= operation[2].length;
		y = Math.pow(10, l);
		operation[2] = parseInt(operation[2]);
		operation[0]+=(operation[2]/y);
		document.getElementById("output").innerHTML = operation[0];
		
	} else if (decimal_two) {
		operation[1]= operation[1].toString();
		var l = operation[1].length;
		var y = Math.pow(10,l);
		operation[0]-=(operation[1]/y);
		operation[1]*=10;
		operation[1]+=x;
		operation[1]= operation[1].toString();
		l= operation[1].length;
		y = Math.pow(10, l);
		operation[1] = parseInt(operation[1]);
		operation[0]+=(operation[1]/y);
		document.getElementById("output").innerHTML = operation[0];
	} else {
		operation[0]*=10;
		document.getElementById("output").innerHTML = operation[0]+=x;
	}
};

Explanation on Code

The code is composed of 2 parts. The HTML has buttons which when pressed they run a function. The JavaScript is the one doing the calculations. I copied some relevant lines where the problem might be.
Decimal_two and Decimal are activated when I press the Button with id="comma", one is used when for the first number, the other for the second. I had to separe them as when I use .reverse(), the array position which stores the decimals move from 2 to 1. I won't explain more unless somebody asks for it. Let's move to the bug.

Getting NaN

I can easily assign decimal positions to the first numbers and do things like the next:

  • 1 + 1
  • 1.2 + 3
  • 1.2345 + 6

But when it comes to assigning decimal digits to the second number, i get NaN. The following is the steps I do:
Any number +... / Press 5 / Press the comma button / Press a number
As soon as I press the number which will go into the decimal place, I get NaN on the output. I have no idea why this happens, I have read it many times, but I keep getting NaN and can't find the mistake.

Let me say Thousands of Thanks to anyone who solves this. If you need any extra part of the code, let me know, I just posted this because I think it's the most relevant part but I may have missed something.

:smiley: Thx


#2

Ok maybe it's just me not being a native speaker but isn't it decimal fraction and not decimal? Decimal just means any number in base 10 (0,1,2,3,4,5,6,7,8,9) instead of e.g. base 2 (0,1). Anyway I guess one needs more information what are for example x and y initially and what do you try to do there with your arrays. Also you might google parseFloat() if you want to deal with floating point numbers (probably what you mean by decimals), and if you use parseInt for parseFloat you might use ,10 as an additional argument to indicate that you are dealing with decimals e.g.

parseInt("100",2) --> 4 whereas parseInt("100",10) --> 100

#3

Hello :smiley:
Thanks for answering back. I am the one who is not a native speaker :stuck_out_tongue: In my country "decimales" is any number after the comma. Sorry for that.

Extra information

The x is the parameter for the function. The if, else if, else statement is inside a function.

var numero = function(x) {
...
}; //This curly bracket was included in previous code.

The 'y' is a local variable. I think that's how they are called. It is defined inside the function and only used inside there. I needed a variable to use only there so I chose the name 'y'. Inside operate() it works as a parameter. In any other place it is just used as a temporary variable.

Talking about what I try to do with the array:

My project is a calculator. Every time I press a button, the function numero() is ran. If the boolean decimal is true (which is activated if I press a comma button), then this happens:
-I turn operation[2] into a string so I can count how many digits it has. Operation[2] is the decimal part (or however they are called in english). For example, the number 4,2 is stored in 2 parts, operation[0] holds 4,2, but operation[2] will be holding the 2.
-Once it becomes a string and I know how many digits it has, I divide it by 10^length so it becomes a floating point number.
-Once it is like that, I substract it from operation[0]. For example: operation[0] = 4.2 ; operation[2] = 2 ; operation[0] -= 2 divided by 10 to its length (in this case 1, therefore, divided by 10).
-I multiply the decimal part by 10 and add the number which was pressed by one of the buttons.
-I check its new length and do the opposite, now I add it.

This was the easiest way I could think of for adding decimal numbers for any case. It works perfectly. The problem is when it comes to the 2nd number. For example, the 5 in "43 + 5". The code will reverse the array so the numbers are always stored in operation[0], and I use decimal_two so it recognized that it has been spinned. Therefore, I had to change the operation[2] to operation[1], as that is the new location for the decimal part to be stored in.
About why I have to do all that of substracting the decimal part, it's so it doesn't stack. For example, 4.2, when you press 3, would become 4.43, as you add 0.23 to the current operation[0].

I hope you could understand my code. Thank you for reading all this :grimacing: I am starting to think that I should simply store the decimals outside the array. The things stored in the array are:
operation[0] = full first number used for the calculation.
operation[1] = arithmetic operation ( +, -, *, /, sqrt, etc).
operation[2] = decimal part but not being a floating point number.
operation[3] = full second number used for the calculation.

When I store the [1] value, I reverse it so I still use operation[0] to show the current number being introduced. That's when I can now activate decimal_two by pressing the comma button, but the function numero() returns NaN...

I have written a lot, sorry for that. I hope you can help, feel free to ask me for the full program, which although it is slightly long, I have no problem in posting it.
:grinning: :smile: :stuck_out_tongue_winking_eye:
Thanks!!!


#4

Ok, now that I read this I guess writing a calculator is not as easy as I thought it is :smile:
And I guess it's better that when you could post your code. I don't know make a githup projekt for this or use a jsfiddle link to have all at once.
Also should this be a simple calculator e.g.

value operator value enter/= -> calculate and show result

or should it also implement priority rules:

power > () > *,/ > +,-

Also as you talk about stacking maybe google this data structure maybe it can help you here. Anyway I think the parsing could be made easier but better present your code first that might make it easier.


#5

I decided to store the decimal part outside the string, I erased the decimal_two variable and function, and the code now works... Thanks for the help :smile: