Habi Hablóg
Declaro:
XML válidoXHTML válido800x600 +
RSS válidoCSS válidoNavegador digno
  Blog   Archivo   Contacto   Administración  

Acerca de

Matemático, informático, aficionado a la electrónica, friki... y otras cosas que no vienen a cuento ni pasan los filtros de palabras.

¿Queríais un blog? Ahí va.

Red antisocial

¡Me van a volver loca! 2.0
La Fragata Portuguesa

Z
¡Me van a volver loca!

Últimos posts

Crackeo preservativo
Restaurando ROMs
Una cosa lleva a la otra
Desbloqueando logros
Teclado en el PCW

Últimos comentarios

genocho
Victor Cortes Abad
Habi
Enrique
Dandare

Calendario

No hay fechas.

Categorías

Chorradas
Paranoias
Posts lúcidos
Tecnoesoterismo
Yuyus

Cenas de Abj

Abj debe 7 cenas.

Frase célebre

Habi dice: Pues por aquí hay un paquete para Abj

Conversión funcional

Habi - 24/04/2009 13:06:17 - Tecnoesoterismo

A veces ocurre que es preferible expresar una determinada propiedad como condición sobre una expresión en vez de una sucesión de sentencias.

Veamos un ejemplo simple. Queremos comprobar que un cierto número X se encuentre entre otros dos cualesquiera A y B.

La forma normal de hacerlo sería ver cuál de los dos números A y B es el mínimo (y por tanto cuál el máximo, pudiendo ser iguales). A continuación se comprueba que X>=Min(A, B) y que X<=Max(A, B).

Sin embargo, esto puede expresarse con una simple fórmula y sin averiguar siquiera quién es el mínimo o el máximo. X está entre A y B si y solamente si (A-X)*(B-X)<=0. Esto bien puede ir como condición de un IF, al contrario que una sucesión de sentencias (en la mayoría de lenguajes imperativos).

Sea F(X)=(A-X)*(B-X). Es obvio que F(A)=F(B)=0. Y que para todo X entre medias, es mayor que uno y menor que el otro (+*- o -*+), luego el signo es siempre negativo. En el caso que sea mayor o menor que ambos, siempre será positivo (+*+ y -*- siempre es +).

Así pues tenemos una expresión booleana aplicable directamente en un IF, si estamos conformes con el coste de la multiplicación (respecto al de la llamada a una función, comparaciones e intercambio) y el resultado no desborda en rango. Si desborda, se usa Signo(A-X)*Signo(B-X) y arreglado.

Una función por el estilo más útil es Signo(A-X)+Signo(B-X), la cual nos devuelve 5 valores según el número sea menor que el mínimo, mayor que el máximo, el mínimo, el máximo o algo intermedio. Esto se deja como ejercicio para el lector.

Aplicado al caso anterior, X está entre A y B si y solamente si Abs(Signo(A-X)+Signo(B-X))<=1, lo cual es obvio si has hecho el ejercicio anterior.


Empecé a practicar este arte en mis tiempos con el Spectrum y su BASIC. Por aquel entonces el BASIC no tenía sutilezas como construcciones WHILE, REPEAT, ENDs para el IF y mucho menos procedimientos y funciones. Ni siquiera había etiquetas, pues cada línea iba numerada.

Y en concreto este dialecto no tenía ni un triste ELSE, mucho menos algo como un ON GOTO ni nada parecido. Sin embargo, tanto el GOTO como el GOSUB esperaban una expresión numérica. Así pues podía hacer por ejemplo un GOSUB 5000+500*A y saltaba a la subrutina adecuada, a partir de 5000 cada 500 lineas.

Se pueden ahorrar también de esta manera instrucciones IF, sabiendo que los operadores relacionales evalúan en {0, 1}. Es válido por tanto GOTO 1234*(A=9)+5678*(A=16), un LET A=27*(A AND 1)-42*(B=13) y cualquier expresión numérica que queráis, incluyendo incluso funciones definidas con DEF FN, etc.

El colmo de lo bizarro era generar en tiempo de ejecución una cadena con la expresión a evaluar y saltar a ella con GOTO VAL(A$), pues VAL convierte de cadena a número... pero esperando igualmente una expresión numérica en formato de cadena.

Ah, que tiempos cuando los lenguajes se parecían al ensamblador quisieran o no.


Zarith - 26/04/2009 11:03:08

Ay, qué genial. 
 
Y ya de temas como legibilidad de código, reutilización, mantenimiento, no hace falta hablar en este foro. 
 
¿Por qué estoy pensando en aquellas prácticas de criptografía de la carrera? 
 
"Para más información, léase código fuente." -> Documentación del trabajo 
 
"ASM: <...>" -> Código fuente 
 
O__o -> Cara del profe 
 
U__u -> Mi cara 
 
^__^ -> H por la cara.



Habi - 29/04/2009 21:50:43

Teniendo en cuenta que mis programas los leo, reutilizo y mantengo yo... ¿dónde está el problema? 
 
Otro ejemplo simple que suelo usar, usando esta vez la notación del C para escribir menos, es hacer que una variable cambie de un valor A a otro B sin IFs ni nada usando un XOR. Basta un x ^= C; donde C=A^B. Por ejemplo X ^= 1824; cambia X de 800 a 1024 y viceversa, útil para alternar modos de video.




Post cerrado