24 de agosto de 2007

Matemáticas chungas

Este primer ejemplo de Mal Código hace gala de poco conocimiento matemático y de que la función ni siquiera se probo si funcionaba.
Partimos de una función existente RandUnsigned que devuelve un valor aleatorio [0, MAX_UNSIGNED_INT]. Tenemos que el valor devuelto ocupa 4 bytes. Si lo que queremos es una función que devuelva valores booleanos aleatorios, lo que no debemos hacer es lo siguiente:
// return random true/false
bool RandomBool(){
// above midvalue
if (RandUnsigned() & 0xFFFF0000)
return false;
else
return true;
}
¿Porque es errónea la función?. Vamos a ver la probabilidad de que devuelva un valor false. Si partimos de que el número devuelto por RandUnsigned es aleatorio, podemos asegurar que un bit cualquiera dentro de este número tendrá la misma probabilidad de estar a uno como de estar a cero, 50% de probabilidad, p = 0,5.
¿Que probabilidad hay de que estén en el mismo estado dos bits cualesquiera? Pues aplicando un poco de matemática básicas, p = 0,5 * 0,5 = 0,25 = 0.5^2. Para que la función devuelva true se tiene que cumplir que los 16 bits más significativos estén a cero (por lo de la comparación con 0xFFFF0000), y la probabilidad de que esto ocurra es de p = 0.5^16 = 0,000015 aprox. Resumiendo, una probabilidad ínfima de obtener el valor true.
Y por esto opino que la función ni siquiera se probo. Por que si se hubiese probado, se habría obtenido pocas veces o ninguna el valor true.

Mi solución
Yo voy a hacer uso de la constante UINT_BITS que es el número de bits que ocupa una variable unsigned int. En nuestro caso este valor es 32.
// return random true/false
bool RandomBool(){
const unsigned int MID_VALUE = 1<<(UINT_BITS - 1);
// above midvalue
return (RandUnsigned() < MID_VALUE);
}
Básicamente la nueva función divide el rango de números en dos mitades iguales [0, MID_VALUE) y [MID_VALUE, MAX_UNSIGNED_INT] y devuelve false o true dependiendo en que mitad caiga el número devuelto por RandUnsigned.
Otra opción hubiese sido simplemente comprobar si un bit cualquiera del número aleatorio es uno o cero. Dependiendo de la máquina en la que se compile puede que se ganen unos pocos ticks de ejecución. Lo que es seguro es que las dos soluciones tenderán a dar los valores false y true con la misma probabilidad, 50% para cada uno, lo que es una gran ventaja respecto a la función original.

21 de agosto de 2007

Presentación

Hola a todos,

Me llamo Luis Cabellos y soy programador. Realmente soy Ingeniero Informático, pero la faceta que quiero mostrar al escribir aquí es la de programador. Programador puro y duro, de los que escriben en un idioma solo entendido por máquinas llamadas ordenadores.

Y el objetivo a corto plazo de lo que quiero hablar es sobre código mal hecho. Código que no hace lo que debe, código que después de leerlo deja mal sabor de boca incluso código que funcionando esta a años luz de ser buen código. Mal Código.

De momento no pienso salirme del ámbito de las aplicaciones reales, hay suficientes ejemplos de mal código como para no necesitar inventarse nada, y en lo que llevo trabajando de programador he visto autenticas barbaridades.

La diferencia de este blog con respecto a otros que también muestran Código Horrible, es que por cada ejemplo de lo que no se debe hacer yo me comprometo a poner como lo haría yo, como creo que debe hacerse. En cada ejemplo de Mal Código puede que me equivoque, por lo que siempre estaré abierto a comentarios. Estoy seguro que siempre se puede aprender cosas nuevas, y en programación más que en ningún otro tema.

Y algún día, quizás me atreva a poner mi propio código, espero que no como ejemplo de mal código, sino para mostrar al mundo lo que yo mismo puedo crear.

Y espero que disfrutéis tanto leyéndome como lo que yo disfrute escribiendo.