Estándar IEEE 754 para la representación en coma flotante

Introducción

La aritmética en coma flotante ha sido objeto de polémicas y múltiples formas de implementarla (quizás más adelante escriba una entrada sobre los métodos más extendidos) pero fue en 1985 cuando el IEEE [1] terminó y publicó un documento donde estandarizaba la forma de representar los números en punto flotante y cómo realizar las operaciones aritméticas. Esta norma se conoce como IEEE 754, y ha sido un fuerte dolor de cabeza para más de un estudiante de Informática en su primer año.

Ha día de hoy se considera el estándar de facto en todos los ordenadores personales. Pero, ¿cómo funciona exactamente?

Representación

Simplificando a dos modalidades la norma define dos resoluciones posibles para los números. Véase la figura 1. Simple precisión (32 bits) y doble precisión (64 bits).

Formato de representación para el estándar IEEE 754 (en simple y doble precisión). Imagen gracias a IBM.

Figura 1: Formato de representación para el estándar IEEE 754 (en simple y doble precisión). Imagen gracias a IBM.

Matemáticamente, ¿cómo funciona este sistema de representación? Dado un número real “x” será representado como su signo, multiplicado por el valor de su mantisa (número normalizado tipo notación científica) y multiplicado además por la base de representación  elavada al valor del exponente sesgado.

(1)
(2)

Hablando en términos de representación numérica en computadores y tomando como ejemplo el caso de simple precisión donde se reserva un bit para el signo, 8 bits para el exponente y 23 bits para la matisa tenemos:

  • Bit de signo: 0 positivo / 1 negativo
  • El exponente se representa sesgado al valor dado por la formula (2). En el caso de simple presición sería: exps = 2^(8-1)-1=2^7-1=127.
  • La mantisa en binario es un número del tipo 1.xxxxx donde el primer 1 no fraccionario se asume y no se representa dentro del formato.
Más adelante realizaremos algún ejemplo práctico, veremos números especiales como NaN , Infinito o el cero. De momento dejo unas curiosidades.

Curiosidades

Número más grande representable:

Número más pequeño representable (positivo y no cero):

Tendiendo a cero hay una serie de números reales no representables:

Referencias

  1. Instituto de Ingenieros Eléctricos y Electrónicos (IEEE o IE3): http://www.ieee.org/index.html
  2. Grupo del IEEE sobre la norma 754: http://grouper.ieee.org/groups/754/
  3. Lecture Notes on the Status of IEEE Standard 754 for Binary Floating-Point Arithmetic: http://www.eecs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF
  4. Conversor entre decimal <–> IEEE754: http://www.h-schmidt.net/FloatConverter/
  5. Conversor entre decimal <–> IEEE754: http://users.minet.uni-jena.de/~sack/SS04/download/IEEE-754.html
  6. http://es.wikipedia.org/wiki/Intel_8087
  7. An Interview with the Old Man of Floating-Point; http://www.cs.berkeley.edu/~wkahan/ieee754status/754story.html
  8. Transparencias muy ilustrativas: http://webdelprofesor.ula.ve/ingenieria/gilberto/paralela/09_AritmeticaPuntoFlotante.pdf

GIT: Repositorios remotos y desarrollo distribuido

Introducción

Hace una semana publiqué una entrada introduciendo el sistema de control de versiones GIT. Ayer añadí otra entrada donde dí unos primeros pasos a git. Hoy después de unas horas de trabajo y recopilar ejemplos basados en mi trabajo diario ha llegado el momento de escribir sobre los repositorio remotos.

Repositorios remotos

Veamos un caso imaginario muy útil. ¿Cual es nuestro escenario?

  • Trabajamos 2+ desarrolladores en un proyecto común.
  • Disponemos de un equipo de trabajo donde día a día actualizamos un repositorio GIT local (a nuestro equipo) para controlar la evolución de nuestro trabajo.
  • Tenemos algún colega/compañero que trabaja desde su casa y también tiene su equipo donde controla su trabajo diario con su instalación local de GIT.
  • Además, cabe la posibilidad que nosotros mismos tengamos en casa otro equipo desde el cual podemos trabajar otras horitas en casa.
La primera pregunta, ¿cómo organizar este lío de tantas personas trabajando en lo mismo sin que haya peligro de sobrescribir uno el trabajo del otro?
Escenario de ejemplo: Repositorios GIT remotos y varios desarolladores
Figura 1: Escenario de ejemplo. Repositorios GIT remotos y varios desarolladores

Bueno, pues ya que hablamos de control de versiones lo primero que entra en juego es un servidor donde crear un/unos repositorio/s GIT donde cada programador realiza un commit de su trabajo y así el resto de colegas estén al tanto de sus cambios (a parte habría que hablar de ciertas políticas o protocolos de trabajo sobre cómo repartir el trabajo pero de eso no hablaremos ahora).

Crear el repositorio en el servidor remoto

Vamos a suponer que disponemos de un servidor con nombre repositorios.net. Este servidor está disponible en Internet o en nuestra red local de trabajo (suponemos una máquina Unix). Hemos creado un usuario llamado git cuya carpeta de trabajo en /home/git. Queremos crear el repositorio para el proyecto ejemplo.

git@repositorios.net:~/$ mkdir ejemplo.git
git@repositorios.net:~/ejemplo.git$ git --bare init
Initialized empty Git repository in /home/git/ejemplo.git/

Ya disponemos de un repositorio (contendor) en crudo donde depositar nuestros commits locales o desde donde descargar las actualizaciones del proyecto realizadas por otros usuarios.

Para poder acceder, desde nuestro directorio de trabajo debemos tener un repositorio git (Vamos a suponer una máquina Windows):

$ git init
Initialized empty Git repository in c:/Workspace/proyecto/.git/
$ git add .
$ git -a -m "Inicio proyecto GIT"

31 files changed, 5873 insertions(+), 0 deletions(-)
create mode 100644 .gitignore
create mode 100644 .project
...
Counting objects: 38, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (37/37), done.
Writing objects: 100% (38/38), 82.87 KiB, done.
Total 38 (delta 1), reused 0 (delta 0)
To ssh://git@repositorios.net/home/git/proyecto.git
* [new branch] master > master

Otro usuario, por ejemplo en un equipo Linux, podría crear su copia de repositorio del siguiente modo:

jperez@jperez-debian:~/gitsample$ git init
Initialized empty Git repository in /home/user/gitsample/.git/
jperez@jperez-debian:~/Desktop/borrar/gitsample$ git remote add Matrix ssh://git@central.ovalus.com:101/home/git/sagema.git
jperez@jperez-debian:~/Desktop/borrar/gitsample$ git pull Matrix
git@central.ovalus.com's password:
remote: Counting objects: 38, done.
remote: Compressing objects: 100% (37/37), done.
remote: Total 38 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (38/38), done.
From ssh://central.ovalus.com:101/home/git/sagema
* [new branch] master -> Matrix/master
You asked to pull from the remote 'Matrix', but did not specify
a branch. Because this is not the default configured remote
for your current branch, you must specify a branch on the command line.
jperez@jperez-debian:~/Desktop/borrar/gitsample$ git pull Matrix master
git@central.ovalus.com's password:
From ssh://central.ovalus.com:101/home/git/sagema
* branch master -> FETCH_HEAD
jperez@jperez-debian:~/Desktop/borrar/gitsample$ ls
css geo.html google848132b663ce25f4.html index.htm js menu.html responsive robots.txt template.php
jperez@jperez-debian:~/Desktop/borrar/gitsample$ ls -lha
total 76K
drwxr-xr-x 6 jperez jperez 4,0K jun 24 17:05 .
drwxrwxr-x 3 jperez jperez 4,0K jun 24 17:02 ..
drwxr-xr-x 3 jperez jperez 4,0K jun 24 17:05 css
-rw-r--r-- 1 jperez jperez 881 jun 24 17:05 geo.html
drwxr-xr-x 8 jperez jperez 4,0K jun 24 17:05 .git
-rw-r--r-- 1 jperez jperez 46 jun 24 17:05 .gitignore
-rw-r--r-- 1 jperez jperez 53 jun 24 17:05 google848132b663ce25f4.html
-rw-r--r-- 1 jperez jperez 4,1K jun 24 17:05 index.htm
drwxr-xr-x 3 jperez jperez 4,0K jun 24 17:05 js
-rw-r--r-- 1 jperez jperez 8,6K jun 24 17:05 menu.html
-rw-r--r-- 1 jperez jperez 599 jun 24 17:05 .project
drwxr-xr-x 4 jperez jperez 4,0K jun 24 17:05 responsive
-rw-r--r-- 1 jperez jperez 61 jun 24 17:05 robots.txt
-rw-r--r-- 1 jperez jperez 12K jun 24 17:05 template.php
jperez@jperez-debian:~/Desktop/borrar/gitsample$

Apéndice 1: .gitignore

**.gitignore** es un fichero especial para GIT. Se debe situar en la carpeta raíz del repositorio. Contiene los ficheros que no queremos que añada GIT al repositorio (de modo que no serán tenidos en cuenta).

¿Esto es útil? Ya lo creo. Supongamos que trabajamos en un proyecto WEB. Seguramente no querremos añadir los ficheros de imágenes, PDS (photoshop), etc.Si se tratase de un proyecto C++ en Linux seguramente sólo querríamos guardar los ficheros .c y .h. De modo que no querremos guardar los ficheros objeto (.o). En definitiva tratamos de evitar cualquier recurso que no sea código fuente o texto.

Un ejemplo, el caso del proyecto C/C++, no queremos que se tengan en cuenta los ficheros *.o, el directorio tmp (que se usa para almacenar datos temporales de compilación) y otras carpeta que se llama “resources”.

*.o
tmp/
resources/

Considero este tema muy interesante, recomiendo leer la entrada [2].

Referencias

  1. Trabajando con repositorios remotos (Doc oficial de GIT) : http://git-scm.com/book/es/Fundamentos-de-Git-Trabajando-con-repositorios-remotos
  2. Ignorando archivos en GIT: http://es.gitready.com/beginner/2009/01/19/ignoring-files.html

GIT: Guía sencilla para su uso cotidiano

Introducción

Hace unos días publiqué una entrada introduciendo el sistema de control de versiones GIT. Voy a provechar esta entrada para explicar de una forma muy sencilla cómo instalarlo y empezar a trabajar con él.

Instalación en Linux

En Linux es muy sencillo de instalar, desde la propia página WEB nos muestran cómo instalarlo en varias distribuciones:

Distro Comando para su instalación
Debian/Ubuntu
$ apt-get install git 
Fedora
$ yum install git 
Gentoo
$ emerge --ask --verbose dev-vcs/git 
Arch Linux
$ pacman -S git 
FreeBSD
$ cd /usr/ports/devel/git && make install 
Solaris 11 Express
$ pkg install developer/versioning/git 
OpenBSD
$ pkg_add git 

Instalación en Windows

Debemos acceder al apartado de descargas: http://git-scm.com/downloads y obtenerr la versión de Windows. Es un sencillo programa de instalación en modo de asistente (el clásico siguiente-siguiente-siguiente).

Yo recomiendo marcar durante la instalación la opción “Git Bash Here” que nos permite a través del botón derecho del ratón abrir un shell (bash de mingw) en la carpeta que indiquemos. Resulta más cómodo.

Primeros pasos

Supongamos que trabajamos en un proyecto PHP, C u otro lenguaje de programación. Lo primero que hemos de hacer es situarnos en la carpeta raíz del proyecto (Ej: /home/user(projects/gitsample) y crear un repositorio. Si estamos en linux desde el terminal navegamos hasta la carpeta y en Windows con la opción del menú contextual “Git bash here” podemos abrir una consola en esa misma carpeta. Tecleamos los siguientes comandos:

$ git init
$ git add .
$ git commit -m "Estado inicial del proyecto"

¿Qué hemos hecho?

  1. Hemos creado el repositorio (git init, ver carpetas ocultas)
  2. Hemos añadido TODOS los ficheros/carpetas al repositorio (git add .). Es decir, le notificamos que los tenga en cuenta para cualquier cambio.
  3. Realizamos el primer commit del proyecto obteniendo una imagen de su estado inicial (git commit -m MENSAJE)

Conforme trabajemos podemos ir anotando todos los cambios diarios en el proyecto. Por ejemplo del siguiente modo:

$ git add .
$ git commit -a -m "Fecha de hoy: Que cambios hice"

Pero, ¿qué pasa si un día me pongo a trabajar y “me cargo” el proyecto? ¿Cómo lo restablezco todo? ¿Cómo vuelvo a una versión anterior de un fichero? Existen varías formas, pero la más simple es esta (leer la documentación para conocer otros casos y opciones):

$ git reset --hard
$ git reset /directorio/al/fichero/a/recuperar

Este es básicamente el día a día que se lleva a cabo con el control de versiones. En mi caso uso la herramienta gráfica SmartGIT para visualmente consultar todos los diff de los ficheros y como van evolucionando a través de los commit. Si bien es cierto que estos últimos meses trabajo con Aptana Studio y uso directamente algunas de sus herramientas gráficas para manejar GIT.

Proximamente

Otras de las características interesantes de GIT es la posibilidad de trabajar con repositorios distribuidos, ramas y tags. En futuras entradas hablaré de estas funcionalidades.

Referencias

  1. Git sitio WEB oficial: http://git-scm.com/
  2. Manual de referencia de Git :http://git-scm.com/docs
  3. Guía rápida muy útil:http://www.edy.es/dev/docs/git-guia-rapida/
  4. Blog oficial de GIT: http://git-scm.com/blog