La familia de ingeniería en Excel parece ser el rincón más fácil de la referencia de funciones. DEC2BIN convierte un número en una cadena binaria, y HEX2DEC vuelve a convertirlo. IMSUM suma dos números complejos. Parece ser que cada una de ellas es un ejercicio de formateo. Pero no lo son. Detrás de esos nombres se esconde una codificación del complemento a dos de diez bits que la mayoría de desarrolladores no ha tocado desde las clases de arquitectura informática, un formato de números complejos que habita en las cadenas únicamente, y unos operadores bit a bit que desbordan un entero de 64 bits silenciosamente si cambia de valor antes de verificar. Un motor de hoja de cálculo que reproduce el Excel a la perfección no puede redondear nada de esto
Las funciones se dividen en tres grupos, de los cuales cada uno esconde una trampa distinta. La conversión de bases se trata de números negativos y de los umbrales por base. La aritmética compleja consiste en analizar sintácticamente y formatear una cadena. Las operaciones bit a bit giran en torno a mantenerse dentro de los límites de Int64. Este artículo aborda cada grupo del modo que lo implementa HotXLS, con las llamadas de las hojas de cálculo que usted escribiría verdaderamente
La conversión de base y el complemento a dos de diez bits
La dirección hacia adelante es la parte que todo el mundo espera. DEC2BIN(9) otorga "1001", y un segundo argumento opcional rellena con ceros a la izquierda el resultado hasta alcanzar un ancho fijo. La trampa reside en las entradas negativas. El Excel no escribe signos de resta. Codifica el valor como una cadena de complemento a dos de diez dígitos en la base de destino, que es el motivo por el cual DEC2BIN(-5,10) devuelve "1111111011" en lugar de algo con un signo. El argumento de los lugares se ignora cuando el valor es negativo, porque la codificación ya está fijada en diez dígitos
Diez dígitos supone un presupuesto fijo, el cual establece el rango representable por base. En binario, la magnitud que pasa a la mitad negativa es 512, y el módulo envolvente es 1024, de modo que una cadena binaria tiene signo solo si su longitud es exactamente de diez caracteres y su valor es al menos 512. La misma idea aumenta con la base. El octal utiliza un medio umbral de 2^29 y un módulo completo de 2^30. El hexadecimal emplea 2^39 y 2^40. El lector de HotXLS aplica exactamente esta norma: acumula los dígitos, y no es hasta que la cadena posee diez caracteres de ancho y el valor acumulado está en el medio umbral o por encima que el lector resta el módulo completo para recuperar el valor firmado. Una cadena de nueve caracteres es siempre no negativa, independientemente de lo grande que sea
El codificador es la imagen del espejo. Un valor no negativo se convierte dígito a dígito y de forma opcional se puede rellenar con ceros hasta el ancho solicitado, y se rechazará en caso de que desborde el techo positivo de la base o si el ancho requerido es demasiado estrecho para soportarlo. Un valor negativo se introduce primero en el rango añadiendo el módulo completo, que lo convierte en un valor cuya representación de base siempre es de diez dígitos; a continuación, los dígitos se emiten con ceros iniciales hasta completar el ancho. La única verificación de rango compartida, los límites inferiores y superiores simétricos por base, es lo que mantiene DEC2BIN, DEC2OCT y DEC2HEX consistentes entre ellas en sus bordes
Lo que nos deja con las conversiones cruzadas de base, las que, por ejemplo HEX2BIN y OCT2HEX, cambian de base sin pasar por el decimal del nombre de la función. La implementación no lleva a cabo una rutina distinta por cada par ordenado. La entrada de cadena la analiza a un valor decimal firmado con la base origen, y después formatea el valor decimal en la base de destino. El decimal es el giro. Una rutina de analizar sintácticamente y una de formatear abarcan todas las combinaciones, y debido a que las dos mitades comparten la misma convención de firma de diez dígitos, un valor negativo sobrevive al viaje con su signo intacto
Los números complejos son cadenas, de manera que el trabajo consiste en el análisis sintáctico
Excel no tiene ningún tipo de datos complejos. Un valor complejo equivale a la cadena "a+bi", y las funciones de la familia IM se encargan de obtener dichas cadenas y entregar una. COMPLEX construye la cadena con una parte real y una parte imaginaria. IMSUM, IMSUB, IMPRODUCT y IMDIV analizan de forma sintáctica sus argumentos, llevan a cabo la aritmética de las partes numéricas, y por último formatean de nuevo el resultado para convertirlo en una cadena. El trabajo numérico es igual al de álgebra en una licenciatura. La dificultad recae enteramente en lograr convertir el texto de forma fiable en dos números de punto flotante, y por eso el analizador interno cobra relevancia
Es muy fácil equivocarse con un par de detalles del analizador. El primero es la unidad imaginaria vacía. La cadena "i" equivale a i una vez, no un error ni cero, por lo que cuando el coeficiente delante de un sufijo está vacío o es un signo de suma solitario, el analizador debe leerlo como el valor 1; lo mismo para un signo de resta solitario, que será -1. Sálteselo e IMSUM("i","i") dejará de ser 2i. El segundo radica en la notación científica chocando con el signo que separa la parte real y la parte imaginaria. El analizador encuentra ese separador debido a que escanea en busca de signos de suma o de resta, pero un número escrito de este modo: "1.5E-3" contiene un signo de resta que le pertenece al exponente. Por lo que la revisión rechaza tratar un signo de suma o resta como un separador cuando el carácter de justo en frente es una e o una E. Sin dicha barrera de defensa, la parte real terminaría partida por la mitad debido al signo del exponente y la revisión fallaría en una entrada totalmente válida
El sufijo mismo se preserva en vez de normalizarse. El Excel acepta i y j, y HotXLS se acuerda de cuál usó la entrada para que el resultado formateado conlleve la misma letra. Después, el formateo se aplica las abreviaturas convencionales: una parte imaginaria de valor 1 se imprime únicamente como sufijo; el -1 como -i; una parte imaginaria equivalente a cero decae en una parte real y simple; y una parte real equivalente a cero elimina el 0+ inicial
var
Book: TXLSXWorkbook;
Sheet: TXLSXWorksheet;
begin
Book := TXLSXWorkbook.Create;
try
Sheet := Book.Sheets.Add('Engineering');
// Negative input: a ten-bit two's complement, places argument ignored.
Sheet.Cells[1, 1].Value := Sheet.Calculate('=DEC2BIN(-5,10)'); // 1111111011
// Complex multiply on two "a+bi" strings.
Sheet.Cells[2, 1].Value := Sheet.Calculate('=IMPRODUCT("3+4i","1+2i")'); // -5+10i
finally
Book.Free;
end;
end;
Las funciones trascendentales complejas, entre ellas IMSQRT, IMEXP, IMLN y IMPOWER, no funcionan con coordenadas rectangulares. Estas convierten el valor analizado hacia la forma polar, aplican la operación al módulo y al argumento y lo vuelven a convertir al resultado inicial. Una raíz cuadrada reduce a la mitad el argumento y toma la raíz del módulo. Una potencia multiplica el argumento y eleva el módulo. Hacerlo de cualquier otra forma significaría rederivar cada identidad a la forma rectangular, lo cual resulta en más código y menos estabilidad numérica cerca de los cortes de ramificación
Los operadores bit a bit y el desbordamiento que se debe comprobar primero
Excel 2013 sumó a sus filas BITAND, BITOR, BITXOR, BITLSHIFT y BITRSHIFT. Los operandos están restringidos: de modo que cada uno tiene que ser un entero no negativo ni más grande que 2^48 menos 1; por su parte, cualquier argumento fraccionario o negativo equivale a un error numérico. Tal límite es lo suficientemente amplio para cubrir un conjunto realista de marcas mientras se mantiene bien adentro del rango representable de exactitud del doble; esto es importante dado que Excel transmite cada argumento numérico como si se tratara de un valor de punto flotante
Las funciones de desplazamiento o cambio sí que llevan una norma de orden que verdaderamente molesta. Un desplazamiento a la izquierda (left shift) puede lograr que se produzca un valor mucho más alto que el de entrada, y si en consecuencia, se lleva a cabo primero un shl y después se inspecciona el resultado, significa que usted ya ha desbordado su Int64 y que dicha prueba carece de sentido. La verificación debe realizarse antes del desplazamiento. HotXLS compara al operando en contraste con el techo desplazado hacia la derecha debido a la cantidad de desplazamiento, y es solamente cuando el operando se adapta que se lleva a cabo un desplazamiento a la izquierda. Se rechaza instantáneamente una magnitud de desplazamiento por encima de 53 bits y un desplazamiento negativo únicamente gira hacia la dirección opuesta; así BITLSHIFT junto a un recuento negativo actúa como si fuese un desplazamiento hacia la derecha. Este principio es general para el resto de esta única función: cuando existe una barrera de defensa para evitar un desbordamiento, este se debe aplicar a las entradas y no al resultado que pretendía proteger
// Bitwise calls evaluate the same way through Calculate.
Sheet.Cells[3, 1].Value := Sheet.Calculate('=BITAND(13,11)'); // 9
Sheet.Cells[4, 1].Value := Sheet.Calculate('=BITLSHIFT(5,2)'); // 20
Sheet.Cells[5, 1].Value := Sheet.Calculate('=BITRSHIFT(40,3)'); // 5
Las futuras funciones y el prefijo de nomenclatura _xlfn
Los operadores bit a bit y la enorme y variopinta lista de sumas y complementos luego del 2007 interactúan con el esquema de nomenclatura que nada tiene que ver con cómo se calculan, sino que está plenamente vinculado a cómo se guardan en el Excel. El formato de la hoja de cálculo binaria original le asignó una ranura numérica en una tabla estática a cada una de sus funciones base. Toda función nacida después de que la tabla quedó en su etapa congelada se quedó sin una de estas ranuras. Para poder guardar tales funciones en un archivo y a su vez que un Excel en versión moderna los pueda reconocer, se decidió que el nombre se escriba con el prefijo _xlfn., de forma que el disco guarda el BITAND como _xlfn.BITAND, a pesar de que el usuario lo tipea únicamente como BITAND
La trampa del asunto es que no se trata de una regla para todos. Algunas de las nuevas funciones sí poseen estas ranuras de las tablas y, por ende, se las escribe al natural, mientras que en algunos casos de las funciones de herencia ocultas también se las escribe sin el prefijo independientemente del tiempo que pasaron con nosotros. HotXLS lleva consigo una lista de admisión expresa y rigurosa en relación a los nombres que necesitan los prefijos, agregándolos en la etapa de lectura y descartándolos en la de lectura; de este modo, el texto de la fórmula que usted defina y vuelva a leer, será siempre un nombre de cara al Excel. Usted lo define como =BITLSHIFT(5,2), el archivo guarda _xlfn.BITLSHIFT, y el valor vuelve como 20 sin que importen las condiciones o pormenores. El prefijo no es más que un detalle del almacenamiento que nunca tendría que inmiscuirse en las fórmulas con las que se trabaja en el código
Unificándolo todo en la hoja de cálculo
La vista superficial general para todo el tema es pequeña. Es necesario que se cree un TXLSXWorkbook, agregue una hoja de cálculo, y luego usted puede tipear una fórmula dentro de una célula, valiéndose para ello de Cells[Row, Col].Formula y a su vez que la vuelva a calcular; o que, por el contrario, que lleve a cabo una evaluación de forma directa con el método Calculate de la hoja de cálculo, el cual va a compilar de nuevo la fórmula en contraposición con dicha página de cálculo y por último va a entregar un Variant. En el caso de los ejemplos anteriores, estos le dan uso al Calculate en tanto que dejan al descubierto el resultado de una llamada de ingeniería unitaria que no se encuentra en el estado de la hoja colindante; sin embargo, y de manera idéntica, las mismas funciones se encargan de llevar a cabo sus evaluaciones en las fórmulas de célula correspondientes, ello una vez que el libro en cuestión vuelve a calcular sus cuentas y fórmulas
Lo que en verdad se debe tomar en cuenta en el proceso son las codificaciones y no las webs donde se originan las llamadas. En el caso de las cadenas binarias, estas vienen con firmas para solo diez dígitos y si pasan del medio umbral en lo que a su respectiva base concierne. Un número complejo se considera texto, mientras que un coeficiente imaginario vacío equivale a uno, y el analizador se encarga de saltarse la e del exponente. Resulta mandatorio comprobar los desplazamientos a la izquierda (left shifts) antes de ejecutar dicho desplazamiento. Si se logran estos cuatro hechos de la manera más adecuada, se logrará entonces que la familia de la ingeniería en general detenga su provisión de desatinos signados
De tal manera, si el plan incluye en un futuro cablear la matemática de su propio dominio al mismo motor base, la mecánica de registrar a un gestor, además de los valores de respuesta, se analizan en profundidad en nuestro artículo que versa sobre cómo extender el motor de las fórmulas con las funciones personalizadas, y cuando dichas fórmulas deben atravesar las hojas por su nombre correspondiente en lugar del nombre de la dirección de la célula, el recorrido de los nombres elegidos y de cómo cruzar las fórmulas de las hojas vislumbrarán cómo se resolverán dichas referenciaciones. Las funciones de ingeniería que se abordan aquí se despachan formando parte del componente de hojas de cálculo de HotXLS para uso tanto de Delphi como del C++Builder, los que, junto con la APIs destinadas a leer, escribir, además de calcular, que a su vez se analizan por igual a lo largo de este blog