Calculadora en Javascript

A continuación se muestra un ejemplo relativamente complejo como puede ser una calculadora. Se han implementado las operaciones básicas. Se podrían añadir más funciones, pero considero que con las implementadas cumple el objetivo de servir de muestra y de paso puede resultar útil. Se puede manejar tanto con el ratón como con el teclado, si bien no todas teclas responden al teclado (las básicas si).

Estilos utilizados

.tecla {
  width: 30px;
  height: 30px;
  text-align: center;
  font-size: 12px;
  font-weight: bold;
}
.display {
  font: bold italic 14px Verdana, Arial, Helvetica, sans-serif;
  text-align: right;
  background-color: black;
  color: lime;
  width: 100%;
  height: 22px;
  border: 3px ridge blue;
}

Código JavaScript

var control = 0;
var operando1, operando2;
var operador;
var memoria = 0;

function redondeo(Valor, decimales)
{
	var temp = Math.pow(10.0, decimales);
	return Math.round(Valor * temp) / temp;
}
  
function convertirMoneda(cambio)
{
  var cantidad = document.forms["FCalculadora"].pantalla.value * cambio;
  document.forms["FCalculadora"].pantalla.value = redondeo(cantidad, 3);
}

function insertaPunto()
{
  var valor = eval("document.forms['FCalculadora'].pantalla.value");
  if (control==0)
    {
    if(valor.indexOf('.') == -1)
      eval("document.forms['FCalculadora'].pantalla.value = document.forms['FCalculadora'].pantalla.value + '.'");
    }
  else
    {
    document.forms["FCalculadora"].pantalla.value = "0.";
    control=0;
    }
  document.forms["FCalculadora"].pantalla.focus(); 
}

function insertaNumero(num)
{
  if(eval("document.forms['FCalculadora'].pantalla.value == '0'") || control == 1)
    {
    eval("document.forms['FCalculadora'].pantalla.value = num");
    control = 0;
    }
  else
    eval("document.forms['FCalculadora'].pantalla.value = document.forms['FCalculadora'].pantalla.value + num");
  document.forms["FCalculadora"].pantalla.focus(); 
	}
function borrar()
{
  if (document.forms["FCalculadora"].pantalla.value == '0') 
    {
    operando1=null;
    operando2=null;
    }
  document.forms["FCalculadora"].pantalla.value = '0';
  document.forms["FCalculadora"].pantalla.focus(); 
}
	
function operacion(op)
{
  var aux = eval("document.forms['FCalculadora'].pantalla.value");  //Para acumular operaciones anteriores
  if (operando1!=null)
    {
    resultado();
    operando1=eval("document.forms['FCalculadora'].pantalla.value");
    }
  else
    operando1 = aux;
  operador = op;
  control = 1;
  document.forms["FCalculadora"].pantalla.focus(); 
}
		
function resultado()
{
  operando2 = eval("document.forms['FCalculadora'].pantalla.value");
  if(operando1 != "" && operando1 != null && operador != "" && operador != null &&
   operando2 != "" && operando2 != null)
    {
    var total = eval("parseFloat(operando1)" + operador + "parseFloat(operando2)");
    if(isNaN(total))
      eval("document.forms['FCalculadora'].pantalla.value = 'Error'");
    else
      eval("document.forms['FCalculadora'].pantalla.value = total");
    control = 1;
    }
  operando1=null;
  operando2=null;
  document.forms["FCalculadora"].pantalla.focus(); 
}

function porcentaje()
{
  operando2 = eval("document.forms['FCalculadora'].pantalla.value");
  eval("document.forms['FCalculadora'].pantalla.value = (operando1 * operando2) / 100");
  control = 1;
  document.forms["FCalculadora"].pantalla.focus(); 
}
	
function guardarMemoria(signo)
{
  var valor = eval("document.forms['FCalculadora'].pantalla.value");
  if(signo == '-')
    memoria = parseFloat(memoria) - parseFloat(valor);
  else
    memoria = parseFloat(memoria) + parseFloat(valor);
  document.forms["FCalculadora"].pantalla.focus(); 
}
	
function recuperarMemoria()
{
  eval("document.forms['FCalculadora'].pantalla.value = memoria");
  document.forms["FCalculadora"].pantalla.focus(); 
}

function borrarMemoria()
{
  memoria = 0;
  document.forms["FCalculadora"].pantalla.focus(); 
}

function cambiaSigno()
{
  var valor = eval("document.forms['FCalculadora'].pantalla.value");
  if(valor.indexOf('-') == 0)
    valor = valor.substring(1);
  else
    valor = '-' + valor;
  eval("document.forms['FCalculadora'].pantalla.value = valor");
  document.forms["FCalculadora"].pantalla.focus(); 
}
	
function recogerTecla(evt)
{
  var keyCode = document.layers ? evt.which : document.all ? evt.keyCode : evt.keyCode;		
  var keyChar = String.fromCharCode(keyCode);

  if(keyCode==13)  //Si se pulsa enter da directamente el resultado
    resultado();
  else{//Si se pulsa una tecla distinta de enter	
    switch (keyCode)
      {
      case 96:{
         keyChar="0";break;}	
      case 97:{
         keyChar="1";break;}
      case 98:{
         keyChar="2";break;}
      case 99:{
         keyChar="3";break;}
      case 100:{
         keyChar="4";break;}
      case 101:{
         keyChar="5";break;}
      case 102:{
         keyChar="6";break;}
      case 103:{
         keyChar="7";break;}
      case 104:{
         keyChar="8";break;}
      case 105:{
         keyChar="9";break;}
      case 106:{ //si se pulsa la tecla x del teclado numerico
         operacion('*');break;}	
      case 107:{ //si se pulsa la tecla + del teclado numerico
         operacion('+');break;}	
      case 109:{ //si se pulsa la tecla - del teclado numerico
         operacion('-');break;}	
      case 111:{ //si se pulsa la tecla / del teclado numerico
         operacion('/');break;}	
      case 188:   //Si se pulsa coma o punto inserta un punto y convierte la cantidad
      case 190:
      case 110: {
         insertaPunto();break;}
      case 8:   //si se pulsa la tecla borrar (backspace) borrar el ultimo digito
         document.forms["FCalculadora"].pantalla.value=document.forms["FCalculadora"].pantalla.value.substr(0,document.forms["FCalculadora"].pantalla.value.length-1);
         break;
      case 27:	//Tecla Esc
      case 67:{
         borrar();break;}	
      case 76:{
         Funcion('log');break;}	
      case 83:{
         Funcion('sin');break;}	
      case 84:{
         Funcion('tag');break;}	
      case 88:{
         invertir();break;}	
      }	
    
    for (i = 0; i<10 ; i++)  //Para el teclado numerico
      {
      if (keyChar==i){					
        if (document.forms["FCalculadora"].pantalla.value =="0" || control==1)			
          {	
          document.forms["FCalculadora"].pantalla.value = i;
          control=0;						
          }	
        else 
          document.forms["FCalculadora"].pantalla.value = document.forms["FCalculadora"].pantalla.value + i;
        }				
      }// fin del for				
    }		
    document.forms["FCalculadora"].pantalla.focus(); 
}

function invertir()
{
  var valor = eval("document.forms['FCalculadora'].pantalla.value");
  valor=1/parseFloat(valor)
  eval("document.forms['FCalculadora'].pantalla.value = valor");
  document.forms["FCalculadora"].pantalla.focus(); 
  control = 1;
}

function Funcion(nombre)
{
  var valor = eval("document.forms['FCalculadora'].pantalla.value");
  valor = eval("Math." + nombre + "(document.forms['FCalculadora'].pantalla.value)");
  eval("document.forms['FCalculadora'].pantalla.value = valor");
  document.forms["FCalculadora"].pantalla.focus(); 
  control = 1;
}

Código HTML

<body onload="document.forms['FCalculadora'].pantalla.value='0';document.forms['FCalculadora'].pantalla.focus();">
....

<form name="FCalculadora" action="javascript:resultado();">
<table border="1" cellpadding="0" cellspacing="0">
  <tr><td colspan="6" align="center">
    <input type="text" class="display" name="pantalla" value="0" align="middle" onKeyDown = "javascript:recogerTecla(event)" readonly>
    </td></tr>
  <tr>
    <td colspan=3><input type="button" value="€->Ptas" style="width: 100%;" onclick="convertirMoneda(166.386);" class="tecla"></td>
    <td colspan=3><input type="button" value="Ptas->€" style="width: 100%;" onclick="convertirMoneda(1/166.386);" class="tecla"></td>
  </tr>
  <tr>
    <td><input type="button" value="1/x" onclick="invertir();" class="tecla"></td>
    <td><input type="button" value="Ln" onclick="Funcion('log');" class="tecla"></td>
    <td><input type="button" value="sin" onclick="Funcion('sin');" class="tecla"></td>
    <td><input type="button" value="cos" onclick="Funcion('cos')" class="tecla"></td>
    <td><input type="button" value="tag" onclick="Funcion('tan');" class="tecla"></td>
    <td><input type="button" value="C" onclick="borrar();" class="tecla"></td>
  </tr>
  <tr>
    <td><input type="button" value="MC" onclick="borrarMemoria();" class="tecla"></td>
    <td><input type="button" value="7" onclick="insertaNumero('7');" class="tecla"></td>
    <td><input type="button" value="8" onclick="insertaNumero('8');" class="tecla"></td>
    <td><input type="button" value="9" onclick="insertaNumero('9');" class="tecla"></td>
    <td><input type="button" value="/" onclick="operacion('/')" class="tecla"></td>
    <td><input type="button" value="Sqrt" onclick="Funcion('sqrt');" class="tecla"></td>
  </tr>
  <tr>
    <td><input type="button" value="MR" onclick="recuperarMemoria();" class="tecla"></td>
    <td><input type="button" value="4" onclick="insertaNumero('4');" class="tecla"></td>
    <td><input type="button" value="5" onclick="insertaNumero('5');" class="tecla"></td>
    <td><input type="button" value="6" onclick="insertaNumero('6');" class="tecla"></td>
    <td><input type="button" value="*" onclick="operacion('*');" class="tecla"></td>
    <td><input type="button" value="%" onclick="porcentaje();" class="tecla"></td>
  </tr>
  <tr>
    <td><input type="button" value="M-" onclick="guardarMemoria('-');" class="tecla"></td>
    <td><input type="button" value="1" onclick="insertaNumero('1');" class="tecla"></td>
    <td><input type="button" value="2" onclick="insertaNumero('2');" class="tecla"></td>
    <td><input type="button" value="3" onclick="insertaNumero('3');" class="tecla"></td>
    <td><input type="button" value="-" onclick="operacion('-');" class="tecla"></td>
    <td rowspan="2"><input type="button" value="=" onclick="resultado();" class="tecla" style="height: 62px;"/></td>
  </tr>
  <tr>
    <td><input type="button" value="M+" onclick="guardarMemoria('+');" class="tecla"></td>
    <td><input type="button" value="0" onclick="insertaNumero('0');" class="tecla"></td>
    <td><input type="button" value="," onclick="insertaPunto();" class="tecla"></td>
    <td><input type="button" value="-/+" onclick="cambiaSigno();" class="tecla"></td>
    <td><input type="button" value="+" onclick="operacion('+')" class="tecla"></td>
  </tr>
</table>
</form>