Încatenarea mai multor operații într-un calculator JavaScript (Programare, Javascript, Calculator)

aasonu a intrebat.

Am creat un calculator de bază în JavaScript care ia valoarea din innerHTML și efectuează calculele, și cam funcționează, doar că nu înlănțuie operații multiple, adică 1 + 2 returnează 3, dar 1 + 2 + 1 returnează și 3. Vă rog să mă ajute cineva cu acest lucru mulțumesc.

https://jsfiddle.net/d2x6e7aj/

HTML-ul meu:

<!DOCTYPE html>
<html>
  
  <head>
    <meta charset="UTF-8">
    <title>Calculator</title>
    <link rel="stylesheet" href="main.css">
  </head>
  
  <body>
    <h1 id="field">myCalculator</h1>
    <table>
      <tr>
        <td id="main" colspan="4">
          <div id="display1"></div>
        </td>
      </tr>
      <tr>
        <td class="numbers"><button id="power">^</button></td>
        <td class="numbers"><button id="squareroot">√</button></td>
        <td class="numbers"><button id="delete">DEL</button></td>
        <td class="numbers"><button id="clear">C</button></td>
      </tr>
      <tr>
        <td class="numbers"><button class='btn-input'>0</button></td>
        <td class="numbers"><button class='btn-input'>1</button></td>
        <td class="numbers"><button class='btn-input'>2</button></td>
        <td class="numbers"><button id="divide">/</button></td>
      </tr>
      <tr>
        <td class="numbers"><button class='btn-input'>3</button></td>
        <td class="numbers"><button class='btn-input'>4</button></td>
        <td class="numbers"><button class='btn-input'>5</button></td>
        <td class="numbers"><button id="multiply">*</button></td>
      </tr>
      <tr>
        <td class="numbers"><button class='btn-input'>6</button></td>
        <td class="numbers"><button class='btn-input'>7</button></td>
        <td class="numbers"><button class='btn-input'>8</button></td>
        <td class="numbers"><button id="subtract">-</button></td>
      </tr>
      <tr>
        <td class="numbers"><button class='btn-input'>9</button></td>
        <td class="numbers"><button id="dot">.</button></td>
        <td class="numbers"><button id="add">+</button></td>
        <td class="numbers"><button id="equals">=</button></td>
      </tr>
    </table>
    
    <script src="main.js"></script>
  </body>
  
</html>

Și JavaScript:

"use strict";
let display = document.getElementById("display1");

function operatorButton() {
    var button = document.getElementById("squareroot");
    button.addEventListener("click", function () {
        display.innerHTML += "√";
    })
    var button = document.getElementById("power");
    button.addEventListener("click", function () {
        display.innerHTML += "^";
    })
    var button = document.getElementById("divide");
    button.addEventListener("click", function () {
        display.innerHTML += "/";
    })
    var button = document.getElementById("multiply");
    button.addEventListener("click", function () {
        display.innerHTML += "*";
    })
    var button = document.getElementById("subtract");
    button.addEventListener("click", function () {
        display.innerHTML += "-";
    })
    var button = document.getElementById("add");
    button.addEventListener("click", function () {
        display.innerHTML += "+";
    })
    var button = document.getElementById("dot");
    button.addEventListener("click", function () {
        display.innerHTML += ".";
    })
    var button = document.getElementById("clear");
    button.addEventListener("click", function () {
        display.innerHTML = "";
    })
    var button = document.getElementById("delete");
    button.addEventListener("click", function () {
        display.innerHTML = display.innerHTML.slice(0, display.innerHTML.length - 1);
    })
}
operatorButton();

function numButton() {
    let button = document.querySelectorAll('.btn-input');
    for (let i = 0; i < button.length; i++) {
        button[i].addEventListener("click", function () {
            display.innerHTML += i
        })
    }
}
numButton();

const addition = (operand1, operand2) => operand1 + operand2;
const subtraction = (operand1, operand2) => operand1 - operand2;
const multiplication = (operand1, operand2) => operand1 * operand2;
const division = (operand1, operand2) => operand1 / operand2;
const squareroot = (operand1) => Math.sqrt(operand1);
const power = (operand1, operand2) => Math.pow(operand1, operand2);

function operate(operand1, operator, operand2) {
    switch (operator) {
        case '^':
            return power(operand1, operand2);
        case '/':
            return division(operand1, operand2);
        case '*':
            return multiplication(operand1, operand2);
        case '+':
            return addition(operand1, operand2);
        case '-':
            return subtraction(operand1, operand2);
        default:
            break;
    }
}
operate();

function operate1(operator, operand1) {
    switch (operator) {
        case '√':
            return squareroot(operand1);
        default:
            break;
    }
}
operate1();

function calculator() {
    var button = document.getElementById("equals");
    button.addEventListener("click", function () {
        let calculation = display.innerHTML.split('');
        let operation, answer, operand1, operand2;
        for (let i = 0; i < calculation.length; i++) {
            if (calculation[i] === "^" || calculation[i] === "/" || calculation[i] === '*' || calculation[i] === "+" || calculation[i] === "-") {
                let operationPos = calculation.indexOf(calculation[i]);
                operation = calculation[i];
                operand1 = parseFloat(calculation.slice(0, operationPos).join(''));
                operand2 = parseFloat(calculation.slice(operationPos + 1).join(''));
                answer = operate(operand1, operation, operand2);
                display.innerHTML = (answer);
            } else if (calculation[i] === "√") {
                let operationPos = calculation.indexOf(calculation[i]);
                operation = calculation[i];
                operand1 = parseFloat(calculation.slice(operationPos + 1).join(''));
                answer = operate1(operation, operand1);
                display.innerHTML = (answer);
            }
        }
    })
}
calculator();

Comentarii

  • Vreți să știți cum se face corect? Puteți studia aici: flatassembler.github.io/compiler.html Sau, dacă robustețea nu este prea importantă pentru tine, uită-te aici: flatassembler.github.io/calculator.html –  > Por FlatAssembler.
  • Văd că ai scris funcții doar pentru a le apela o singură dată (cele cu ascultătorul de evenimente) – de ce nu le-ai configurat fără funcții? –  > Por iAmOren.
  • pentru a analiza șirul de calculatoare ar trebui să te adaptezi la precedența operatorilor – așa cum s-a sugerat în unele răspunsuri – asta înseamnă stive, push, pops. Ați putea folosi eval, dar îmi place cum arată logica ta. dacă folosești eval ar trebui să adăugați Math.sqrt și Math.pow (și paranteze de închidere) în jurul lor în valoarea calculatorului care urmează să fie evaluată… –  > Por iAmOren.
4 răspunsuri
cazononsensibil

În funcția dvs. calculator() treceți în buclă peste elementele cu for (let i = 0; i < calculation.length; i++) {. Ceea ce lipsește aici este stocarea rezultatului intermediar și folosirea lui ca operand1 atunci când este calculat.

crazyX

Poți avea o matrice de operatori (+, – … etc.) și să împarți șirul de intrare prin operatori, care îți va crea o matrice cu numere care vor fi calculate, apoi doar încearcă să găsești un algoritm de calcul folosind prioritățile operațiilor (‘(‘, /, *, +, -, etc.).

grzesiekmq

atunci când sunt mai mult de 2 valori, vă sugerez să puneți numerele în array și să le cumulați cu reduce()
Mă refer la adunare, înmulțire, împărțire etcpentru că ai doar doi operanzi trebuie să cumulezi valoarea
în general, 1+2+11*2*11/2/1
Adică trebuie să aveți un acumulator pentru a opera pe următoarele valori.
sau să folosiți închiderea cu rezultat intermediar
dar în cazul reduce() văd un neajuns, deoarece funcționează cu un singur operator la un moment dat, de exemplu, doar cu suma valorilor.
Presupun că doriți să combinați operatorii de tipul 1+2*1.
deci utilizarea închiderii ar trebui să fie în regulă.

obscuritate

Să presupunem că introducem un calcul de tipul 1+2+2 în calculator și apăsăm butonul egal. În cadrul gestionarului de evenimente click al butonului egal, acesta transformă acest șir de caractere într-o matrice de caractere simple:

[„1″,”+”,”2″,”+”,”2″]

din cauza acestei linii:

let calculation = display.innerHTML.split('');

Acum, acest lucru este grozav dacă doriți într-adevăr vreodată să calculați doar numere cu o singură cifră, dar va eșua dacă are mai multe.

De ex. 12+2+2 se va transforma în [„1″,”2″,”+”,”2″,”+”,”2″]

Există o modalitate mai elegantă de a separa operatorii de numere prin utilizarea unui expresie regulată.

Deci, să ne uităm la un alt exemplu – să folosim următorul calcul:

var str = "124-2+3*10";

și introducem acest șir în această expresie regulată:

var calculation = str.match(/d+|[^0-9]/g);

acum matricea returnată va arăta cam așa:

[ „124”, „-„, „2”, „+”, „3”, „*”, „10” ]

Site-ul d+ se potrivește cu orice număr, în timp ce [^0-9] se potrivește cu orice lucru care nu este un număr.

Dacă dorim să includem numere zecimale, operația de mai sus ar eșua, deoarece punctul ar fi tratat ca nefiind un număr și, astfel, ar împărți un număr zecimal în două.

Pentru a rezolva această problemă, putem îmbunătăți expresia regulată pentru a include numere zecimale, de exemplu:

var calculation = str.match(/d+.d+|d+|[^0-9]/g);

Acum este doar o chestiune de a face o buclă peste matricea returnată, de a afla dacă elementul curent este un operator și de a face calculele, ca să spunem așa.

Aflarea dacă este un număr sau un operator se face folosind funcția isNan(input) care încearcă mai întâi să convertească datele de intrare într-un număr și, în cazul în care nu reușește, returnează funcția false.

Iată un exemplu:

Vă rugăm să rețineți: Acesta nu este modul în care funcționează în mod normal calculatoarele. De asemenea, această soluție nu ia în considerare numerele negative. Este doar ceva pentru a vă ajuta să începeți.