JS Calculator: Unexpected Results

10

I created a simple calculator in JavaScript, but some results are going wrong, for example, operations like '10 +10 '(returns 18) or '20 / 2' (returns 8). I'm still learning to tinker with the language, so it may be that the error is quite simple, but I can not see anything in the code that causes this.

var array = [];

// acionado ao clicar em números ou operadores
// inclui os todos numeros e operadores a um array
// exibe no paragrafo de id 'txt' o número ou operador que foi pressionado por ultimo
function funcao(param) {
  var txt = document.getElementById('txt');
  array.push(param);
  txt.innerHTML = (param);
}

// acionado ao clicar na opção =
// passa todos os itens do array para uma variavel e depois usa 'eval()' para calcular a operação
// exibe o resultado no paragrafo de id 'txt'
function resultado() {
  var result = 0;
  for (var i = 0; i < array.length; i++) {
    result += array[i];
  }
  result = eval(result);
  txt.innerHTML = (result);
}

// acionado ao clicar na opção C
// remove todos os itens do array
// passa o valor da variavel result para zero
// volta a exibir apenas um espaço no paragrafo de id 'txt'
function limpar() {
  for (var c = 1; c < array.length; c++) {
    array = array.splice();
  }
  result = 0;
  txt.innerHTML = " ";
}
#tela {
  border: 1px solid #000;
  width: 200px;
  padding: 10px;
  text-align: right;
  margin-bottom: 5px;
}

button {
  border: none;
  margin: 2px;
  padding: 10px;
  width: 49px;
  height: 50px;
}
<!-- dentro do paragrafo foi adicionado um espaço em branco por questões visuais (alt+255) -->
<div id='tela'>
  <p id='txt'> </p>
</div>

<!-- cada botao chama a função funcao() com o seu valor, sendo números ou operadores -->
<button onclick="funcao('1')">1</button>
<button onclick="funcao('2')">2</button>
<button onclick="funcao('3')">3</button>
<button onclick="funcao('+')">+</button><br>

<button onclick="funcao('4')">4</button>
<button onclick="funcao('5')">5</button>
<button onclick="funcao('6')">6</button>
<button onclick="funcao('-')">-</button><br>

<button onclick="funcao('7')">7</button>
<button onclick="funcao('8')">8</button>
<button onclick="funcao('9')">9</button>
<button onclick="funcao('*')">*</button><br>

<!-- as funções limpar() e resultado() são para zerar a calculadora e mostrar o resultado, respectivamente-->
<button onclick="limpar()">c</button>
<button onclick="funcao('0')">0</button>
<button onclick="resultado()">=</button>
<button onclick="funcao('/')">/</button>
    
asked by anonymous 18.12.2017 / 02:01

1 answer

5

The problem is how you start the text that corresponds to the result calculation:

function resultado() {
    var result = 0; //<--aqui
    for (var i=0;i<array.length;i++) {
        result += array[i];
    }
    result = eval(result);
    txt.innerHTML = (result);
}

You are putting a zero at startup and when you add the rest ahead it will not be correct and eval can not give the desired result.

As @AndersonCarlosWoss indicated in the comments that having zero before causes the "10+10" fault to actually be "010+10" which is evaluated to 18 because the first number is interpreted as octal. This interpretation is because the number starts with 0 , and 010 in octal corresponds to 8 in decimal, which when you add 10 gives 18 you indicated in question.

Instead you should start the result with empty text:

var result = "";

See how it works with this change:

<!DOCTYPE html>
<html lang="pt-br">
<head>

    <title>Calculadora</title>

    <meta charset="utf-8">
    <style type="text/css">
        #tela {
            border: 1px solid #000;
            width:200px;
            padding:10px;
            text-align:right;
            margin-bottom:5px;
        }

        button {
            border:none;
            margin:2px;
            padding:10px;
            width:49px;
            height:50px;
        }
    </style>
</head>
<body>
    <!-- dentro do paragrafo foi adicionado um espaço em branco por questões visuais (alt+255) -->
    <div id='tela'><p id='txt'> </p></div>

    <!-- cada botao chama a função funcao() com o seu valor, sendo números ou operadores -->
    <button onclick="funcao('1')">1</button>
    <button onclick="funcao('2')">2</button>
    <button onclick="funcao('3')">3</button>
    <button onclick="funcao('+')">+</button><br>

    <button onclick="funcao('4')">4</button>
    <button onclick="funcao('5')">5</button>
    <button onclick="funcao('6')">6</button>
    <button onclick="funcao('-')">-</button><br>

    <button onclick="funcao('7')">7</button>
    <button onclick="funcao('8')">8</button>
    <button onclick="funcao('9')">9</button>
    <button onclick="funcao('*')">*</button><br>

    <!-- as funções limpar() e resultado() são para zerar a calculadora e mostrar o resultado, respectivamente-->
    <button onclick="limpar()">c</button>
    <button onclick="funcao('0')">0</button>
    <button onclick="resultado()">=</button>
    <button onclick="funcao('/')">/</button>

    <script type="text/javascript">
        var array = [];

        // acionado ao clicar em números ou operadores
        // inclui os todos numeros e operadores a um array
        // exibe no paragrafo de id 'txt' o número ou operador que foi pressionado por ultimo
        function funcao(param) {
            var txt = document.getElementById('txt');
            array.push(param);
            //console.log(array);
            txt.innerHTML = (param);
        }

        // acionado ao clicar na opção =
        // passa todos os itens do array para uma variavel e depois usa 'eval()' para calcular a operação
        // exibe o resultado no paragrafo de id 'txt'
        function resultado() {
            var result = "";
            for (var i=0;i<array.length;i++) {
                result += array[i];
            }
            result = eval(result);
            txt.innerHTML = (result);
        }

        // acionado ao clicar na opção C
        // remove todos os itens do array
        // passa o valor da variavel result para zero
        // volta a exibir apenas um espaço no paragrafo de id 'txt'
        function limpar() {
            for(var c = 1; c<array.length; c++) {
                array=array.splice();
            }
            result = 0;
            txt.innerHTML = " ";
        }
    </script>
</body>

I do not know if the idea was to practice using arrays, because if you are merely concatenating a string to do eval it was much simpler to use just string to do everything:

let calculo = "";
const txt = document.getElementById('txt');

function funcao(param) {
    txt.innerHTML = param;
    calculo += param;
}

function resultado() {
    txt.innerHTML = eval(calculo);
}

function limpar() {
    calculo = "";
    txt.innerHTML = " ";
}
<!DOCTYPE html>
<html lang="pt-br">
<head>

    <title>Calculadora</title>

    <meta charset="utf-8">
    <style type="text/css">
        #tela {
            border: 1px solid #000;
            width:200px;
            padding:10px;
            text-align:right;
            margin-bottom:5px;
        }

        button {
            border:none;
            margin:2px;
            padding:10px;
            width:49px;
            height:50px;
        }
    </style>
</head>
<body>
    <!-- dentro do paragrafo foi adicionado um espaço em branco por questões visuais (alt+255) -->
    <div id='tela'><p id='txt'> </p></div>

    <!-- cada botao chama a função funcao() com o seu valor, sendo números ou operadores -->
    <button onclick="funcao('1')">1</button>
    <button onclick="funcao('2')">2</button>
    <button onclick="funcao('3')">3</button>
    <button onclick="funcao('+')">+</button><br>

    <button onclick="funcao('4')">4</button>
    <button onclick="funcao('5')">5</button>
    <button onclick="funcao('6')">6</button>
    <button onclick="funcao('-')">-</button><br>

    <button onclick="funcao('7')">7</button>
    <button onclick="funcao('8')">8</button>
    <button onclick="funcao('9')">9</button>
    <button onclick="funcao('*')">*</button><br>

    <!-- as funções limpar() e resultado() são para zerar a calculadora e mostrar o resultado, respectivamente-->
    <button onclick="limpar()">c</button>
    <button onclick="funcao('0')">0</button>
    <button onclick="resultado()">=</button>
    <button onclick="funcao('/')">/</button>
</body>
    
18.12.2017 / 02:20