Construí una calculadora simple usando Javascript, pero cuando hago operaciones como 012 + 3 siempre me devuelve 13 y no 15...!
Además, en mi Calculadora cuando divido cualquier número con 0 me devuelve "Infinito" pero quiero devolver "Error" o "No es calculable" como cadena. ¿Qué puedo hacer en este caso?
Pasé mucho tiempo buscando soluciones aquí en StackOverflow porque noté que este problema es muy frecuente, pero no encontré una solución realmente adaptable para mi código.
Aquí mi código:
let output = document.getElementById('output'); let cells = Array.from(document.getElementsByClassName('cell')); // console.log(cells); cells.map(cell => { cell.addEventListener('click', (e) => { /* console.log('clicked'); console.log(e); console.log(e.target); console.log(e.target.innerText); */ switch (e.target.innerText) { case 'C': output.innerText = ''; break; case '=': // Funzione di gestione degli errori; try { output.innerText = eval(output.innerText); } catch { output.innerText = 'Error!'; } break; default: output.innerText += e.target.innerText; } }); });
<div> <div class="calculator"> <div id="output"></div> <div class="buttons"> <button class="cell operator">+</button> <button class="cell operator">*</button> <button class="cell operator">/</button> <button class="cell operator">-</button> <button class="cell">7</button> <button class="cell">8</button> <button class="cell">9</button> <button class="cell">4</button> <button class="cell">5</button> <button class="cell">6</button> <button class="cell">1</button> <button class="cell">2</button> <button class="cell">3</button> <button class="cell">0</button> <button class="cell">.</button> <button class="cell">C</button> <button class="cell result">=</button> </div> </div> </div>
Una solución funcional podría ser eliminar el 0 inicial antes de eval.
let output = document.getElementById('output'); let cells = Array.from(document.getElementsByClassName('cell')); // console.log(cells); cells.map(cell => { cell.addEventListener('click', (e) => { /* console.log('clicked'); console.log(e); console.log(e.target); console.log(e.target.innerText); */ switch (e.target.innerText) { case 'C': output.innerText = ''; break; case '=': // Funzione di gestione degli errori; try { output.innerText = eval(output.innerText.replace(/^0+/, '')); } catch { output.innerText = 'Error!'; } break; default: output.innerText += e.target.innerText; } }); });
<div> <div class="calculator"> <div id="output"></div> <div class="buttons"> <button class="cell operator">+</button> <button class="cell operator">*</button> <button class="cell operator">/</button> <button class="cell operator">-</button> <button class="cell">7</button> <button class="cell">8</button> <button class="cell">9</button> <button class="cell">4</button> <button class="cell">5</button> <button class="cell">6</button> <button class="cell">1</button> <button class="cell">2</button> <button class="cell">3</button> <button class="cell">0</button> <button class="cell">.</button> <button class="cell">C</button> <button class="cell result">=</button> </div> </div> </div>
No escribiré su código por usted, pero señalaré dónde están sus problemas para que pueda continuar. Tienes dos problemas diferentes que has señalado.
Cuando usa "0" como el comienzo de un número entero en javascript, se reconocerá como un número octal o de base 8, por lo que "012" en base 8 podría ser algo así como 10 en decimal, sumando 3 a eso equivaldrá a 13. I No conozco los detalles exactos de esto, pero tendrá problemas si usa números enteros que comienzan con 0, por lo que debe asegurarse de eliminar los ceros iniciales de los números enteros.
Para su segundo problema, una solución rápida es usar isFinite
( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isFinite ) para ver si la división es infinita, sin embargo, la solución adecuada sería asegurarse de no dividir por cero o lanzar una excepción.
Debe realizar más manipulación de cadenas (como eliminar 0) en output.innerText
antes de poder eval
.
Su solución está aprovechando la función eval()
. Entonces obtienes el comportamiento de esta función. Si intenta ingresar las mismas operaciones en una consola Javascript (pruebe con su navegador), obtendrá los mismos resultados.
En cuanto a la explicación de por qué 012 + 3 = 13
: un 0
inicial significa que el número literal será octal (base 8).
Entonces 012
en base 10 es
1 * 8 ^ 1 + 2 * 8 ^ 0 = 8 + 2 = 10
En base 10, 10 + 3 = 13, obviamente.
Evitar esto implicará un trabajo mucho más complicado. Incluso si pudieras deshacerte fácilmente de los ceros iniciales, no habrás solucionado el problema del Infinity
. Hay otros valores que también podrían devolverse, por ejemplo, 0/0
devuelve NaN
.
Y también, tenga cuidado con los posibles problemas de seguridad de eval()
.