JavaScript Calculator Zero digits, Decimal, Negative(-) numbers

JavaScript Calculator Zero digits, Decimal, Negative(-) numbers
0.0 0

#1

I’m having 3 issues and trying to solve with many ways, but couldn’t come up with the solutions…

  1. Zero before digits (I’ve tried many ways with regex, but even though it was matching the pattern, still didn’t solve my issues.)

Here you can see the screenshot of one of the regex I’ve used:

Still had an issues after applying this type of regex. (right now I took this regex out from my codepen)

  1. Decimal
    I found a way to not repeat the (.) But don’t know how to not repeat when it has already on the group of numbers like this:

  1. Negative numbers
    Still not sure how to not make the “-” to apply to the last digits after clicking +/_ button:

I appreciate for your time, and any help or advice or “solution” :upside_down_face: you can give me.
Thanks :smiley:


#2

There are really many ways you could go about solving those problems. Here are a few suggestions:

1. Trimming leading-zero

  • Since you are storing everything as strings in an array, perhaps you could consider String(Number(num))—converting a string into a number will remove any leading zeros, after which you can convert it back into a string
  • If you want to stick with regex, perhaps you could try something like /^0*(.+)/* lets you match the preceding expression 0 or more times and + lets you match the preceding expression 1 or more times

I think the String(Number(num)) method may be more elegant as there are may be edge cases with the regex method that requires much more effort to take care of (I’m guessing that it will mostly depend on how you implement decimal points)

2. Decimal

I haven’t looked too closely at how you are handling . but, assuming that you are sticking it into a number once it’s pressed, could you simply use the response of str.match('.') to decide what the response should be?

3. +/- Button

Assuming that you have the means to select the last number of the two, I think you can use a similar method to the one mentioned in 1—simply convert the string corresponding to the number of interest into a, well, number, make it negative, and convert it back to a string!

The only issue will then be handling the sign before the second number, but that ultimately depends on how you want to represent the second negative sign visually, since it won’t affect your calculations.

I hope that helps! Good luck!


#3

There is actually a really simple way of solving the calculator problem !
the eval function
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
like you can just copy the content of calculator as a string from DOM and use this function
to get the actual output

this actually converts a string of no. and expressions to a solved integer ! !

eval("00+22") 
output: 22 // the output will be an integer  

as for the other scenarios you can deactivate the buttons once they are clicked

bonus :

eval("any no./0") //output : Infinity 
eval("0/0") //output:NaN

Not sure if this helps , but worked for me!
Cheers!


#4

I do use eval() for all of results. You can check my codepen, eval() is in button-result(=). Everything works great, I guess what I’m trying to do is just to fix this little problems. For example eval() doesn’t understand this “- -1.8.3.5 + 000.2.4.6” lol :sweat_smile:
But Thank you for your answer, eval() actually saves me from bunch of extra code :wink:


#5

You will have to check the user’s input each time a key is pressed and not allow duplicate operators like – or ++ or multiple decimals.


#6

Yes, I handle that with RegExp under the name symbols. It doesn’t let the keys like (+ - * / ) to be repeated. However when I press (+/-) for first number works great, and when I press second time the regex doesn’t let it to be repeated. But when I do some operations like “-0.1+23” and press the (+/-) for “23” the button finds first number and adds the “-“ so 0.1 gets another “-“ instead of “23”. I’m assuming my RegExp doesn’t work for this case.


#7

I appreciate for your answer and I hope your answer will be helpful for others. But for now I decided to go with another way, because I was mostly using arrays instead of strings or numbers. Right now I fixed my issues and it’s working)) I’m so happy :smiley: Thank you so much, your answer rocks! :+1:t2:


#8

Alright, this is for the reader who has the same issues which I had.
If you decided to use regex for testing, and store all values from buttons inside of array than you can continue reading this, otherwise see the answer from @honmanyau which is really useful :+1:t2:

Array?

If you store all the values to array and every time user clicks the buttons will push it to array, than it’s not a bad idea to clean up from empty strings.

var arr = [];
$('.button').on('click', function() {
  arr.push($(this).attr('value'));
  arr = arr.filter(function(n) { return n != ""; }); 

});

And now every time you arr.splice() this code will handle all of the empty values. Console.log(arr) and you will see what I mean.
This is the kind of issues I had. The arr was something like [“1”, “2”, “7”, " ", " "] which will go way worst when you keep splicing it…

The RegExp

The regex is best, in my opinion, to actually not try to come up with something cool which will test everything at one time. It’s best by testing or matching piece by piece. Don’t come up with something like this for zeros, unless it worked for you :wink: /because for me didn’t))

Use something like this if you are matching zeros:

//zeros
 if(arr.join('').match(/^0\d+/)){
   arr.splice(-2, 1);
   $('.result').text(arr.join(''));
 } else if(arr.join('').match(/[^0-9\.]0\d+/)){
   arr.splice(-2, 1);
   $('.result').text(arr.join(''));
 } else if(arr.join('').match(/\.0/)){
    $('.result').text(arr.join(''));
 }

I know there might be a shorter way, but it’s better to make it longer and make sure that will work 100%

Decimals

In my opinion it’s better to manipulate the dot(.) when user clicks on it and take out the value="" from your HTML:

$('.button-decimal').click(function(){
  var lastNum = arr.join('').match(/\.\d+$/);
  if(/[^0-9]$/.test(arr)){
    $('.result').text(arr.join(''));
  } else if(arr.length==0) {
     arr.splice(0, 0, "0.");
     $('.result').text(arr.join(''));
  }else {
     arr.splice(arr.length, 0, ".");
     $('.result').text(arr.join(''));
  }
  if(lastNum.join('').split('').includes('.')){
    arr.splice(-1, 1);
    $('.result').text(arr.join(''));
  }
});

Negative numbers

Alright, you will probably come up with something much better, but I made it really long)) I had the same idea as decimal. Take out the value="" from your HTML, because you will probably have another test to make sure that multiple operators like (±*/) don’t repeat and this going to be handy.

$('.button-negative').click(function(){
    var lastNums = arr.join('').match(/\d+?\.?\d{1,}$/);
    var minusLastNums = arr.join('').match(/-\d+?\.?\d{0,}$/); //-number
    if(!moreThanOneOperators.test(arr)){
      if(minusLastNums){
        arr.splice(-minusLastNums.join('').split('').length, 1);
        $('.result').text(arr.join(''));
      }
      if(arr.length==0){
        arr.splice(0, 0, "-0");
        $('.result').text(arr.join(''));
      }else if(lastNums){
        arr.splice(-lastNums.join('').split('').length, 0, '-');
        $('.result').text(arr.join(''));
      }else if(lastNums==null){
        arr.splice(-1, 0, "-");
        $('.result').text(arr.join(''));
      }      
    }
  });

And we end up with calculator without bugs = 99% . Why only 99%? Well trust me, bugs are still showing up for me at random cases)) But at least the big main problems are far away :+1:t2:

(This is the image with positive 100 +negative (-0.5), but it doesn’t repeat the operators)) don’t worry :wink:)

You can check my Calculator- Codepen
Good Luck :wink: