Desarrollando en Cobol y Natural sobre Plataforma Mainframe

viernes, 20 de diciembre de 2013

Procedimiento DFHYITVL para compilación de CICS

Cuando necesitemos compilar un programa Cobol con transacciones CICS, siempre podremos recurrir al procedimiento estándar DFHYITVL en vez de crearnos nuestro propio JCL de compilación. De esta forma nos ahorraremos todo el trabajo requerido para la generación del módulo del objeto Cobol CICS.

El procedimiento estándar DFHYITVL es un proceso que incluye la compilación del objeto Cobol CICS y su posterior paso de linkedit para generar el módulo asociado. Asimismo, incluye la invocación a un precompilador que procederá a traducir todas las sentencias CICS incluidas en nuestro programa.



El contenido de DFHYITVL es el siguiente:

//DFHYITVL PROC SUFFIX=1$,    Suffix for translator module
//       INDEX='DFH320.CICS', Qualifier for CICS libraries
//       PROGLIB='DFH320.CICS.SDFHLOAD',   Name of o/p library
//       DSCTLIB='DFH320.CICS.SDFHCOB',    Private macro/dsect
//       AD370HLQ='IGY410',   Qualifier for AD/Cycle compiler
//       LE370HLQ='CEE',      Qualifier for LE/370 libraries

//       OUTC=A,                     Class for print output
//       REG=4M,                     Region size for all steps
//       LNKPARM='LIST,XREF',        Link edit parameters
//       STUB='DFHEILID',            Lked INC. for DFHELII

//       LIB='SDFHSAMP',             Library
//       WORK=SYSDA                  Unit for work datasets

//TRN    EXEC PGM=DFHECP&SUFFIX,
//            PARM='COBOL2',                              @01C

//            REGION=&REG                      
//STEPLIB  DD DSN=&INDEX..SDFHLOAD,DISP=SHR
//SYSPRINT DD SYSOUT=&OUTC              
//SYSPUNCH DD DSN=&&SYSCIN,
//            DISP=(,PASS),UNIT=&WORK,

//            DCB=BLKSIZE=400,
//            SPACE=(400,(400,100))
//*

//COB    EXEC PGM=IGYCRCTL,REGION=&REG,
//       PARM='NODYNAM,LIB,OBJECT,RENT,RES,APOST,MAP,XREF'
//STEPLIB  DD DSN=&AD370HLQ..SIGYCOMP,DISP=SHR
//SYSLIB   DD DSN=&DSCTLIB,DISP=SHR           
//         DD DSN=&INDEX..SDFHCOB,DISP=SHR
//         DD DSN=&INDEX..SDFHMAC,DISP=SHR
//         DD DSN=&INDEX..SDFHSAMP,DISP=SHR
//SYSPRINT DD SYSOUT=&OUTC
//SYSIN    DD DSN=&&SYSCIN,DISP=(OLD,DELETE)
//SYSLIN   DD DSN=&&LOADSET,DISP=(MOD,PASS),
//            UNIT=&WORK,SPACE=(80,(250,100))
//SYSUT1   DD UNIT=&WORK,SPACE=(460,(350,100))
//SYSUT2   DD UNIT=&WORK,SPACE=(460,(350,100))
//SYSUT3   DD UNIT=&WORK,SPACE=(460,(350,100))
//SYSUT4   DD UNIT=&WORK,SPACE=(460,(350,100))
//SYSUT5   DD UNIT=&WORK,SPACE=(460,(350,100))
//SYSUT6   DD UNIT=&WORK,SPACE=(460,(350,100))
//SYSUT7   DD UNIT=&WORK,SPACE=(460,(350,100))
//*
//COPYLINK EXEC PGM=IEBGENER,COND=(7,LT,COB)

//SYSUT1   DD DSN=&INDEX..&LIB(&STUB),DISP=SHR
//SYSUT2   DD DSN=&&COPYLINK,DISP=(NEW,PASS),
//            DCB=(LRECL=80,BLKSIZE=400,RECFM=FB),
//            UNIT=&WORK,SPACE=(400,(20,20))
//SYSPRINT DD SYSOUT=&OUTC
//SYSIN    DD DUMMY
//*
//LKED   EXEC PGM=IEWL,REGION=&REG,
//            PARM='&LNKPARM',COND=(5,LT,COB)
//SYSLIB   DD DSN=&INDEX..SDFHLOAD,DISP=SHR
//         DD DSN=&LE370HLQ..SCEELKED,DISP=SHR
//SYSLMOD  DD DSN=&PROGLIB,DISP=SHR
//SYSUT1   DD UNIT=&WORK,DCB=BLKSIZE=1024,
//            SPACE=(1024,(200,20))
//SYSPRINT DD SYSOUT=&OUTC
//SYSLIN   DD DSN=&&COPYLINK,DISP=(OLD,DELETE)
//         DD DSN=&&LOADSET,DISP=(OLD,DELETE)
//         DD DDNAME=SYSIN
                                           

Como vemos, el procedimiento se divide en 4 pasos:

1º)  Traducción CICS: se ejecuta el precompilador CICS denominado DFHECP1$, que procederá a traducir las sentencias CICS que hayamos incluido en nuestro programa Cobol.

2º) Compilador Cobol: realiza la compilación estándar del objeto Cobol. Se trata del proceso IGYCRCTL que se usa para cualquier programa.

3º) Copiar DFHEILID: Crea una copia del objeto DFHEILID, de la librería DFH320.CICS.SDFHSAMP, para que sea usada por el paso de Linkedit.

4º) Linkedition: Se realiza el paso de linkedit del objeto Cobol y se genera la salida en el la librería indicada. En nuestra instalación, se trata de la librería DFH320.CICS.SDFHLOAD.

Con estos 4 pasos, el procedure realiza la compilación completa del programa Cobol que tiene incorporadas las sentencias CICS. Para incluir esta utilidad en nuestra propia compilación únicamente tendremos que incorporar la ejecución de este procedimiento en nuestro JCL.

Finalmente recordar que las librerías incluidas en el DFHYITVL podrían variar un poco en vuestro equipo, dependiendo de la instalación del CICS.


Saludos.

miércoles, 18 de diciembre de 2013

Compilador de objetos Cobol con CICS

En ocasiones, tendremos necesidad de incluir invocaciones CICS en nuestros programas Cobol (por ejemplo, para el tratamiento de Mapas). En estos casos, no podremos recurrir al compilador estándar de objetos Cobol y tendremos que usar un procedimiento especial que tenga en cuenta las transacciones CICS.

Si incluimos una ejecución CICS en nuestro programa Cobol e intentamos compilar de forma estándar, el compilador nos devolverá un error. Esto es debido a que, en estos casos, tenemos que recurrir al procedimiento de compilación denominado DFHYITVL.



Por ejemplo, supongamos que elaboramos un programa Cobol en el que tenemos una invocación CICS a un Mapa del siguiente modo.

*
     EXEC CICS                      
       SEND MAP('JJ0004M')          
       MAPONLY                      
       ERASE                        
       NOHANDLE                     
     END-EXEC.                      
*                 
                   

En casos como estos tendremos que emplear un compilador que disponga de la ejecución correspondiente del procedure DFHYITVL. Por ejemplo, podría ser el siguiente.

//JJCOM4CL JOB (123),'COMPILADOR CICS',CLASS=A,MSGCLASS=A,
//             MSGLEVEL=(1,1),NOTIFY=&SYSUID
//***************************************************

//* DFHYITVL - COMPILADOR DE OBJETOS COBOL CON CICS
//***************************************************

//JOBPROC  JCLLIB ORDER=DFH320.CICS.SDFHPROC
//CICSCOB  EXEC DFHYITVL,      
//             DSCTLIB=LIBPR.COPYS.JJ00,  *LIBRERIA DE COPYS
//             PROGLIB=LIBPR.MODULOS.JJ01 *LIBRERIA DE MODULOS
//* UBICACION DEL PROGRAMA CON CICS
//TRN.SYSIN  DD DSN=LIBPR.FUENTES.JJ00(JJ0004CO),DISP=SHR
//* LIBRERIAS SYSLIB DE IEWL - DFHELII
//LKED.SYSLIB DD DSN=DFH320.CICS.SDFHLOAD,DISP=SHR           
//            DD DSN=CEE.SCEELKED,DISP=SHR
//            DD DSN=LIBPR.MODULOS.JJ01,DISP=SHR       
//LKED.SYSIN DD  * 
  NAME JJ0004CO(R)                                         

//

Como vemos, este compilador especial se compone de un único paso que invoca directamente al procedimiento DFHYITVL. Dicho procedure se encarga de realizar la compilación de los objetos Cobol que tengan transacciones CICS.

En este paso tenemos que especificar los siguientes datos:

1º) Cláusula JCLLIB: Tenemos que especificar la librería en la que se encuentra el objeto DFHYITVL. Esto variará en cada instalación. En nuestro caso, se trata de la librería DFH320.CICS.SDFHPROC.

//JOBPROC  JCLLIB ORDER=DFH320.CICS.SDFHPROC

2º) Parámetro DSCTLIB: Esta es la librería en la que se encuentran las copys que se van a utilizar en nuestro programa Cobol.

//             DSCTLIB=LIBPR.COPYS.JJ00,  *LIBRERIA DE COPYS

3º) Parámetro PROGLIB: Se trata de la librería en la que será almacenado el módulo generado a partir de nuestro programa Cobol.

//             PROGLIB=LIBPR.MODULOS.JJ01 *LIBRERIA DE MODULOS

4º) Parámetro SYSIN: Aquí especificaremos la librería en la que se encuentra el fuente de nuestro objeto Cobol.

//TRN.SYSIN  DD DSN=LIBPR.FUENTES.JJ00(JJ0004CO),DISP=SHR

5º) Parámetro SYSLIB: aquí habrá que especificar, entre otras cosas, la librería en la que se encuentra el objeto IEWL, uno de los empleados en el procedure DFHYITVL. En nuestro caso, se trata de la librería DFH320.CICS.SDFHLOAD.

//LKED.SYSLIB DD DSN=DFH320.CICS.SDFHLOAD,DISP=SHR           
//            DD DSN=CEE.SCEELKED,DISP=SHR
//            DD DSN=LIBPR.MODULOS.JJ01,DISP=SHR        


6º) Por último, al final del compilador tendremos que incluir la cláusula SYSIN indicada en el ejemplo.

//LKED.SYSIN DD  * 
  NAME JJ0004CO(R)


Si se realiza correctamente, no deberíamos tener ningún problema con la compilación de nuestro objeto. La mayor dificultad de este procedimiento es especificar correctamente las librerías en las que se encuentra cada cosa. Debido a que cada instalación es diferente, tendremos que perder algún tiempo en identificarlas pero, una vez superado ese paso inicial, el proceso no debería darnos ningún quebradero de cabeza adicional.

Pues nada, como siempre, esperamos haberos ayudado un poco a ir profundizando en vuestro conocimiento del entorno Cobol.

Saludos.

viernes, 13 de diciembre de 2013

Procedimiento DFHMAPS para compilación de Mapas

Cuando necesitemos compilar un Mapset de Cobol, siempre podremos recurrir al procedimiento estándar DFHMAPS en vez de crearnos nuestro propio JCL de compilación. De esta forma nos ahorraremos todo el trabajo requerido para la generación de los Mapas Simbólico y Físico.

El procedimiento estándar DFHMAPS es un proceso que incluye la compilación de nuestros Mapas mediante el Ensamblador ASMA90, así como de todos los pasos necesarios para chequear si nuestro Mapset tiene algún problema en su estructura.



El contenido de DFHMAPS es el siguiente:

//DFHMAPS PROC INDEX='DFH320.CICS',
//             MAPLIB='DFH320.CICS.SDFHLOAD',         
//             DSCTLIB='DFH320.CICS.SDFHMAC',       
//             MAPNAME=,             
//             A=,                          
//             AMODE=31,    
//             RMODE=ANY,       
//             ASMBLR=ASMA90,       
//             REG=2048K,               
//             OUTC=A,                   
//             WORK=SYSDA                     

//COPY     EXEC PGM=IEBGENER                            
//SYSPRINT DD SYSOUT=&OUTC                             
//SYSUT2   DD DSN=&&TEMPM,UNIT=&WORK,DISP=(,PASS),   

//            DCB=(RECFM=FB,LRECL=80,BLKSIZE=400),       
//            SPACE=(400,(50,50)) 
//SYSIN    DD DUMMY                        
//* SYSUT1 DD * NEEDED FOR THE MAP SOURCE                 
//ASMMAP   EXEC PGM=&ASMBLR,REGION=&REG,              
//* NOLOAD CHANGED TO NOOBJECT
//  PARM='SYSPARM(&A.MAP),DECK,NOOBJECT'                      
//SYSPRINT DD SYSOUT=&OUTC                 
//SYSLIB   DD DSN=&INDEX..SDFHMAC,DISP=SHR
//         DD DSN=SYS1.MACLIB,DISP=SHR               
//SYSUT1   DD UNIT=&WORK,SPACE=(CYL,(5,5))  
//SYSUT2   DD UNIT=&WORK,SPACE=(CYL,(5,5))
//SYSUT3   DD UNIT=&WORK,SPACE=(CYL,(5,5))
//SYSPUNCH DD DSN=&&MAP,DISP=(,PASS),UNIT=&WORK,
//            DCB=(RECFM=FB,LRECL=80,BLKSIZE=400),         
//            SPACE=(400,(50,50)) 
//SYSIN    DD DSN=&&TEMPM,DISP=(OLD,PASS)       
//LINKMAP  EXEC PGM=IEWL,PARM=('LIST,LET,XREF,RMODE(&RMODE)',
//            'AMODE(&AMODE)')
//SYSPRINT DD SYSOUT=&OUTC                           

//SYSLMOD  DD DSN=&MAPLIB(&MAPNAME),DISP=SHR                  
//SYSUT1   DD UNIT=&WORK,SPACE=(1024,(20,20))
//SYSLIN   DD DSN=&&MAP,DISP=(OLD,DELETE)
//* NOLOAD CHANGED TO NOOBJECT
//ASMDSECT EXEC PGM=&ASMBLR,REGION=&REG,
//  PARM='SYSPARM(&A.DSECT),DECK,NOOBJECT'
//SYSPRINT DD SYSOUT=&OUTC               
//SYSLIB   DD DSN=&INDEX..SDFHMAC,DISP=SHR
//         DD DSN=SYS1.MACLIB,DISP=SHR               
//SYSUT1   DD UNIT=&WORK,SPACE=(CYL,(5,5))  
//SYSUT2   DD UNIT=&WORK,SPACE=(CYL,(5,5))
//SYSUT3   DD UNIT=&WORK,SPACE=(CYL,(5,5))
//SYSPUNCH DD DSN=&DSCTLIB(&MAPNAME),DISP=OLD 
//SYSIN    DD DSN=&&TEMPM,DISP=(OLD,DELETE) 
                           

Como vemos, el procedimiento se divide en 4 pasos:

1º) Paso COPY: aquí únicamente se toma el Mapset de la librería origen (indicada por el usuario) y se copia en un Dataset temporal.

2º) Paso ASMMAP: en este punto se aplica el Ensamblador ASMA90 sobre el mapa origen y se genera el Mapset Físico.

3º) Paso LINKMAP: aquí se ejecuta el Binder sobre el mapset creado en el paso anterior. Se genera, en la librería destino, un objeto ejecutable con el Mapset Físico.

4º) Paso ASMDSECT: en este último paso se genera, a partir del mapa origen, el Mapset Simbólico en la librería destino correspondiente.

Y, con estos 4 pasos, el proceso DFHMAPS crea el Mapset Simbólico y el Mapset Físico asociados a nuestro mapa. Para incluir esta utilidad en nuestra compilación únicamente tendremos que incorporar la ejecución de este procedimiento en nuestro JCL.

Finalmente mencionar que las librerías incluidas en el DFHMAPS podrían variar un poco en vuestro equipo, dependiendo de la instalación del CICS.

Saludos.

jueves, 12 de diciembre de 2013

Compilador para Mapas Cobol

Para la compilación de un Mapset (agrupación de Mapas) Cobol no podremos recurrir al compilador estándar de objetos. Esto es debido a que se precisa la intervención de un Ensamblador especial que nada tiene que ver con los procesos empleados para los programas Cobol.

El Ensamblador específico para Mapsets se denomina ASMA90, ubicado en la librería DFH320.CICS.SDFHMAC. Este proceso se encargará de chequear todas las líneas de los Mapas del Mapset  y nos informará si hay algún problema en su estructura.



A continuación, mostramos un ejemplo de cómo quedaría el compilador de Mapsets. Recordad que siempre puede haber alguna pequeña variación de una instalación a otra.

//JJCOM9CL JOB (123),'COMPILADOR MAPSET',CLASS=A,MSGCLASS=A,
//             MSGLEVEL=(1,1),NOTIFY=&SYSUID
//***************************************************

//* DFHMAPS - PROCEDIMIENTO COMPILACION DE MAPSET
//* MAPSET  - AGRUPACION DE MAPAS
//***************************************************
//JOBPROC  JCLLIB ORDER=DFH320.CICS.SDFHPROC      
//CICSMAP  EXEC DFHMAPS2,             *COMPILADOR ASMA90
//         OUTC=*,                    *PRINT SYSOUT CLASS
//         DSCTLIB=LIBPR.COPYS.JJ00,  *DESTINO MAPA SIMBOLICO
//         MAPLIB=LIBPR.MODULOS.JJ01, *DESTINO MAPSET FISICO
//         MAPNAME=JJ0004M            *NOMBRE MAPSET DESTINO
//* UBICACION DEL FUENTE DEL MAPSET
//COPY.SYSUT1  DD  DSN=LIBPR.MAPLIB.JJ00(JJ0004M),DISP=SHR

//
//***************************************************
              

Como vemos, para la implementación de este compilador hemos empleado la invocación al procedimiento estándar DFHMAPS. Dicho procedimiento se encarga de realizar la compilación de nuestro Mapset con el ensamblador ASMA90 y de generar el Mapset Físico asociado.

Para que el funcionamiento sea correcto, a DFHMAPS hay que proporcionarle varios parámetros:

1º) Ubicación del DFHMAPS: que, en nuestro caso, es la librería DFH320.CICS.SDFHPROC. Esto puede variar de una instalación a otra.

//JOBPROC  JCLLIB ORDER=DFH320.CICS.SDFHPROC       

2º) Parámetro DSCTLIB: se trata de la ubicación en la que se va a almacenar el Mapset Simbólico generado por nuestra compilación. En nuestro ejemplo, hemos puesto la librería LIBPR.COPYS.JJ00.

//         DSCTLIB=LIBPR.COPYS.JJ00

3º) Parámetro MAPLIB: es la ubicación en la que deseamos que se almacene el Mapset Físico que se va a generar en nuestra compilación. En el ejemplo, se ha indicado la librería LIBPR.MODULOS.JJ01.

//         MAPLIB=LIBPR.MODULOS.JJ01

4º) Parámetro MAPNAME:  es el nombre que deseamos que tengan el Mapset Simbólico y el Mapset Físico generados. En el ejemplo hemos elegido JJ0004M.

//         MAPNAME=JJ0004M

5º) Ubicación del fuente del Mapset: obviamente, tendremos que indicar la librería en la que se encuentra almacenado el fuente de nuestro Mapset. En el ejemplo, nuestro mapa está en la librería LIBPR.MAPLIB.JJ00.

//COPY.SYSUT1  DD  DSN=LIBPR.MAPLIB.JJ00(JJ0004M),DISP=SHR

Mencionar que, si no queremos usar el procedimiento estándar DFHMAPS, lo único que tendríamos que hacer es crearnos nuestro propio JCL e ir incluyendo los pasos que se van ejecutando en aquel procedimiento (pasos COPY, ASMMAP, LINKMAP y ASMDSECT).

Una vez definidos correctamente todos los parámetros precisados, la ejecución de nuestro compilador de Mapas no debería darnos ningún problema.

Saludos.

miércoles, 11 de diciembre de 2013

Inclusión de librería COPY en el Compilador Cobol

En ocasiones, nuestro programa Cobol llevará alguna sentencia COPY incluida en la sección WORKING-STORAGE. En dichas situaciones, en el compilador tendremos que indicar la ubicación exacta de dicha COPY, identificando la librería que la contiene.



Si incluimos una COPY en nuestro Cobol y lanzamos el Compilador sin más, entonces se generará un mensaje de error informándonos de que no se ha encontrado la librería de copys. Este mensaje, que puede ser un poco confuso, será el siguiente.

The COPY library SYSLIB was not found.

Para informar de la ubicación de la librería de copys a nuestro compilador tendremos que incluir la declaración del parámetro SYSLIB en nuestro JCL. Por ejemplo, si la librería de copys es LIBPR.COPYS.JJ00, entonces la declaración se haría del siguiente modo.

//COBOL.SYSLIB   DD DSN=LIBPR.COPYS.JJ00,DISP=SHR

Tengamos en cuenta que el parámetro SYSLIB tendrá que ser especificado en los dos pasos de nuestro compilador (el paso de Compilación y el paso de Linkedition). Sin embargo, la librería de copys únicamente tendrá que ser indicada en el paso de compilación.

Para verlo más claramente, a continuación mostramos cómo quedaría un Compilador ejemplo, una vez incluidas las dos librerías en SYSLIB.

//JJCOM1CL JOB 102,'COMPILADOR COMPLETO',NOTIFY=&SYSUID,
//  MSGCLASS=Q,CLASS=A,MSGLEVEL=(1,1),REGION=0M,TIME=(0,7)
//**************************************************************   //* SYSLIB  ES LA LIB. DE COPYS 
//* SYSIN   ES LA LIB. DE PROGRAMAS FUENTES
//* SYSLMOD ES LA LIB. DE PROGRAMAS OBJETOS O EJECUTABLES
//************************************************************** //STEP0          EXEC IGYWCLG,PARM.COBOL='LIB,APOST,XREF,MAP,OFFSET'
//* LIBRERIA EN LA QUE SE ENCUENTRA EL COMPILADOR IGYCRCTL
//COBOL.STEPLIB  DD DSN=IGY410.SIGYCOMP,DISP=SHR         
//* LIBRERIA DE FUENTES Y DE COPYS PARA PASO COBOL
//COBOL.SYSIN    DD DSN=LIBPR.FUENTES.JJ00(JJ0004CO),DISP=SHR 
//COBOL.SYSLIB   DD DSN=LIBPR.COPYS.JJ00,DISP=SHR
//* AÑADIMOS COPYS Y MODULOS PARA PASO LKED DE IGYWCL (PGM HEWL)
//LKED.SYSLIB    DD DSN=CEE.SCEELKED,DISP=SHR             

//LKED.SYSLMOD   DD DSN=LIBPR.MODULOS.JJ01(JJ0004CO),DISP=SHR
//
 
                                                        

Como vemos, el compilador se divide en dos partes (paso COBOL y paso LKED), cada una de las cuales tiene su parámetro SYSLIB.

1º) Compilación COBOL: aquí es donde tenemos que especificar, asociado al parámetro SYSLIB, el nombre de la librería donde van a estar almacenadas nuestras copys.

//COBOL.SYSLIB   DD DSN=LIBPR.COPYS.JJ00,DISP=SHR

2º) Linkedition LKED: este es el paso de prelinkedit. Aquí también tendremos un parámetro SYSLIB, pero no hace referencia a nuestras copys del programa Cobol.

//LKED.SYSLIB    DD DSN=CEE.SCEELKED,DISP=SHR

Hay que tener en cuenta que el compilador mostrado valdría únicamente para programas Cobol que no tengan accesos a DB2. En caso contrario, tendríamos que recurrir a un Compilador más completo, del cual ya hemos hablado en otros post anteriores.

Pues nada, incluyendo la librería de Copys tal y como se indica aquí ya no deberíamos tener problemas a la hora de compilar correctamente nuestros Cobol.

Saludos.

martes, 3 de diciembre de 2013

Simulación del lanzamiento de un Dado en Cobol

Desde siempre sabemos que Cobol no es un lenguaje muy preparado para trabajar con generación de números aleatorios. De hecho, en la mayoría de las aplicaciones en las que se usa Cobol dicha necesidad no existe (ya que se trata de aplicaciones de gestión pura). Sin embargo, si alguna vez necesitamos números aleatorios, existe una forma de generalos.

 

Para obtener números pseudo-aleatorios tendremos que recurrir a la función RANDOM. Dicha función procede a generar un número aleatorio a partir de un número Semilla dado. Por tanto, obtener un aleatorio será tan simple como invocar a la función RANDOM con un número predefinido.

FUNCTION RANDOM(SEMILLA)

¿Cuál es el problema de la función RANDOM? Bueno, pues tal y como se indica en su definición, lo que hace es generar números pseudo-aleatorios a partir de una semilla. Y el número generado será siempre el mismo para un número semilla dado. Es decir, si no cambiamos la semilla, la invocación a la función RANDOM nos devolverá siempre el mismo número. De ahí que se denominen pseudo-aleatorios.

Entonces, ¿qué podemos hacer para que nunca invoquemos a RANDOM con la misma semilla? ¿cómo podemos ir consiguiendo números semilla siempre distintos de los anteriores? Pues una forma típica de hacerlo es recurrir a la función CURRENT DATE para crearlos.

FUNCTION CURRENT-DATE

Básicamente, lo que haremos es extraer la Fecha y la Hora (que incluirá hasta las centésimas de segundo) del CURRENT DATE actual y usar ese número como semilla para la obtención de un número aleatorio mediante la función RANDOM.

Obsérvese que una semilla extraída así, con Fecha y Hora, nunca podrá ser igual. Es decir, la Fecha-Hora en un momento dado será 20131203121501 y, un segundo después, será 20131203121502, un número distinto. Y si hacemos la consulta dentro de un año, a la misma hora, será 20141203121502, otro número totalmente distinto de los dos anteriores.

Por tanto, la Fecha-Hora nos va a permitir obtener siempre una semilla totalmente distinta de las que nuestro programa ha podido obtener alguna vez en el pasado. Y, por tanto, eso hará que nuestra función RANDOM genere un número aleatorio totalmente nuevo.

Teniendo en cuenta lo anteriormente indicado, podríamos simular un Dado (en este caso, de 100 caras o, lo que es lo mismo, un Simulador de Percentil) en nuestro programa Cobol de la siguiente forma.

*                                                     
     MOVE FUNCTION CURRENT-DATE TO DATE-TODAY
*                                   
     MOVE FECHA-HORA TO SEMILLA                       
     COMPUTE NUM-RANDOM = FUNCTION RANDOM(SEMILLA)    
       * 10000000000000000                            
     COMPUTE PERCENTIL = NUM-RANDOM / 100000000000000 
     MOVE PERCENTIL TO PERCENTIL-D                      

*

Donde las variables estarán definidas del siguiente modo.

*                           
 01 DATE-TODAY.             
   05 FECHA-HORA  PIC 9(16).
   05 GUION-D     PIC X(1). 
   05 GMT-H       PIC X(2). 
   05 GMT-M       PIC X(2). 
*                             

 01 SEMILLA    PIC 9(16).           
 01 NUM-RANDOM PIC 9(16) COMP-3.    
*                                    

 01 PERCENTIL   PIC 999V99.
 01 PERCENTIL-D PIC ZZ9,99.
*                           


Como vemos, lo que hace esta rutina es cargar la fecha actual en DATE-TODAY. A continuación, se mueve la subvariable FECHA-HORA a la SEMILLA de la función RANDOM. Finalmente, se calcula el PERCENTIL a partir del número aleatorio generado.

La ejecución de esta rutina Cobol muestra la siguiente información:

LEIDOS: 000000000000001             
CURRENT-DATE: 2013120205182478-0600 
FECHA-HORA  : 2013120205182478      
SEMILLA   : 2013120205182478        
NUM-RANDOM: 3017732446555855        
PERCENTIL :  30,17 %                      
***                                       
                            

Como vemos, en este ejemplo hemos generado el número aleatorio 30,17. Tal y como lo hemos definido, nuestro "Dado" obtendrá números entre 0 y 100. Sin embargo, la rutina puede ser fácilmente modificada para obtener únicamente números entre 1 y 6, con lo que tendríamos un "verdadero" Dado.

Y eso es todo. Es evidente que, en el mundo Cobol, en la mayoría de las ocasiones la función RANDOM no no será útil, pero siempre es bueno saber que está ahí, por si algún día la necesitamos.


Saludos.

Related Posts Plugin for WordPress, Blogger...