Funcion I2BIN(n)

Funcion I2BIN(n)

Postby cmsoft » Fri Jun 15, 2018 9:59 am

Estimados:
La función I2Bin(n) de harbour o CA-CLIPPER dice que devuelve una cadena de caracteres de 16 bits en formato binario, pero no lo hace, siempre me devuelve vacio. Se que su aplicación es con ficheros, pero en este caso la necesito para hacer un analisis bit x bit de lo que devuelve una función que maneja status de un controlador fiscal.
Hay alguna función que lo haga? Que dado
512 me devuelva '0000001000000000' ?
Yo hice una pequeña función para hacerlo, pero me gustaria saber si hay alguna de FW o Harbour que lo haga...
Code: Select all  Expand view

? Fi_I2Bin(512,16) //-->'0000001000000000'
? Fi_I2Bin(2,4)    //-->'0010'

STATIC FUNCTION Fi_I2Bin  (nDecimal,nBits)
LOCAL binario
DEFAULT nBits := 0
IF nDecimal <= 1
   binario := str(nDecimal,1)
   ELSE
   binario := Fi_I2Bin(INT(nDecimal*.5)) + STR(nDecimal%2,1)
ENDIF
RETURN IF(nBits==0,binario,REPLICATE("0",nBits-Len(binario))+binario)
 
User avatar
cmsoft
 
Posts: 1189
Joined: Wed Nov 16, 2005 9:14 pm
Location: Mercedes - Bs As. Argentina

Re: Funcion I2BIN(n)

Postby cnavarro » Fri Jun 15, 2018 10:08 am

Prueba

Code: Select all  Expand view

   ? DecToBin( 512 )
 
Cristobal Navarro
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
El secreto de la felicidad no está en hacer lo que te gusta, sino en que te guste lo que haces
User avatar
cnavarro
 
Posts: 6500
Joined: Wed Feb 15, 2012 8:25 pm
Location: España

Re: Funcion I2BIN(n)

Postby cmsoft » Fri Jun 15, 2018 2:35 pm

Perfecto Cristobal, muchas gracias!!
Tendría que ajustarlo para que siempre me devuelva un binario con igual cantidad de caracteres, porque 0 devuelve vacio...
Code: Select all  Expand view

Replicate("0",16-Len(DecToBin (512)))+DecToBin(512)
User avatar
cmsoft
 
Posts: 1189
Joined: Wed Nov 16, 2005 9:14 pm
Location: Mercedes - Bs As. Argentina

Re: Funcion I2BIN(n)

Postby cnavarro » Fri Jun 15, 2018 5:11 pm

Bien
Por el ejemplo que has puesto antes, imaginaba que tendrias que hacer algo asi
O asi
Code: Select all  Expand view

   ? PadL( DecToBin( 512 ), 16, "0" )
 
Cristobal Navarro
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
El secreto de la felicidad no está en hacer lo que te gusta, sino en que te guste lo que haces
User avatar
cnavarro
 
Posts: 6500
Joined: Wed Feb 15, 2012 8:25 pm
Location: España

Re: Funcion I2BIN(n)

Postby nageswaragunupudi » Fri Jun 15, 2018 9:31 pm

NTOC( nInteger ( or cHex ), ;
nBase, ; // 2 to 36. Default 10
nLength, ;
cPadChar ) // default Space.

nBase (also known as RADIX in math) is
for Binary : 2, Octal : 8, Decimal : 10, Hex : 16. We can also choose any other number.

Example
? NTOC( 312, 2, 16, "0" ) --> "0000000100111000"
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10248
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: Funcion I2BIN(n)

Postby xmanuel » Fri Jun 15, 2018 9:37 pm

Tal vez esta propuesta también te guste, está hecha en C y va muy rápida:

Hb_decToBin( numDecimal, nAnchoDelBin ) -> cadena representando el numero decimal pasado a binario con el ancho pasado en el segundo parametro;

Ej. alert( Hb_decToBin( 100, 8 ) ) // Se ve en pantalla 01100100

Code: Select all  Expand view


void decToBin( HB_LONG lDecimal, HB_INT iBits, char *szBinary )
{
    HB_INT i = 0, n = 0, iResto;
    char *szTemp = hb_xgrab( iBits );
   
    // No hay negativos en binario
    if( lDecimal < 0 )
    {
        lDecimal = -lDecimal;
    }
    // Calcula el binario en temp
    do
    {
        iResto = lDecimal % 2;
        lDecimal = lDecimal / 2;
        szTemp[ i++ ] = iResto ? '1' : '0';
    }
    while( lDecimal > 0 );
   
    // Relleno de 0
    while( n < iBits - i )
    {
        szBinary[ n++ ] = '0';
    }
    // Copia del temporal
    while( i >= 0 )
    {
        szBinary[ n++ ] = szTemp[ --i ];
    }
    // Pone el fin de cadena
    szBinary[ n - 1 ] = '\0';

    hb_xfree( szTemp );
}

HB_FUNC( HB_DECTOBIN )
{
    HB_LONG lDecimal = hb_parnl( 1 );
    HB_INT iBits = hb_parnidef( 2, 1 );
    char *szRetBit = hb_xgrab( iBits + 1 );
   
    decToBin( lDecimal, iBits, szRetBit );
   
    hb_retc_buffer( szRetBit );
}
 


Espero que te valga...
______________________________________________________________________________
Sevilla - Andalucía
xmanuel
 
Posts: 756
Joined: Sun Jun 15, 2008 7:47 pm
Location: Sevilla

Re: Funcion I2BIN(n)

Postby nageswaragunupudi » Sat Jun 16, 2018 3:00 am

When there is a highly capable built-in function like NTOC available, we need not write our own functions.
But inspired by Mr. xmanuel, I present here another simpler and faster variation.
Code: Select all  Expand view
#pragma BEGINDUMP

#include <windows.h>
#include <hbapi.h>

HB_FUNC( NUMTOBINARY )
{
   unsigned short n;
   char * cRet = "0000000000000000";
   int i;
   unsigned int digits = ( HB_ISNUM( 2 ) ? hb_parni( 2 ) : 16 );

   digits = ( digits > 16 ? 16 : ( digits < 1 ? 1 : digits ) );
   cRet  += ( 16 - digits );
   n = ( unsigned short ) hb_parnl( 1 );
   for ( i = digits - 1; i >= 0; i-- )
   {
      cRet[ i ] += ( n & 1 );
      n >>= 1;
   }
   hb_retc( cRet );
}

#pragma ENDDUMP
 


Usage:
NUMTOBINARY( number, [nDigits] )
nDigits can be 1 to 16 and if omitted, defaults to 16.
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10248
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: Funcion I2BIN(n)

Postby xmanuel » Sat Jun 16, 2018 7:45 am

Función mejorada...

Pero falla con números negativos y solo soporta un ancho hasta 16, en MySQL los tipos BIT pueden llegar a 64.

Muchas gracias
______________________________________________________________________________
Sevilla - Andalucía
xmanuel
 
Posts: 756
Joined: Sun Jun 15, 2008 7:47 pm
Location: Sevilla

Re: Funcion I2BIN(n)

Postby cmsoft » Sat Jun 16, 2018 5:57 pm

Muchas gracias a todos!!
Habia varias opciones.. Excelente!
User avatar
cmsoft
 
Posts: 1189
Joined: Wed Nov 16, 2005 9:14 pm
Location: Mercedes - Bs As. Argentina

Re: Funcion I2BIN(n)

Postby nageswaragunupudi » Sun Jun 17, 2018 4:22 am

xmanuel wrote:Función mejorada...

Pero falla con números negativos y solo soporta un ancho hasta 16, en MySQL los tipos BIT pueden llegar a 64.

Muchas gracias


Thanks.
Modified the function to handle 64-bit (4 byte) integers (defaults to 16).
Code: Select all  Expand view

#pragma BEGINDUMP

#include <windows.h>
#include <hbapi.h>

HB_FUNC( NUMTOBINARY )
{
   LONGLONG n;
   char * cRet;
   int i;
   unsigned int digits = ( HB_ISNUM( 2 ) ? hb_parni( 2 ) : 16 );

   digits = ( digits > 64 ? 64 : ( digits < 1 ? 1 : digits ) );
   cRet  = hb_xgrab( digits );
   n = hb_parnll( 1 );
   for ( i = digits - 1; i >= 0; i-- )
   {
      cRet[ i ] = ( ( n & 1 ) + '0' );
      n >>= 1;
   }
   hb_retclen( cRet, digits );
   hb_xfree( cRet );
}

#pragma ENDDUMP
 

This function (my previous version also) handles negative numbers correctly.

Code: Select all  Expand view

? "NUMTOBINARY( -100, 64 ):", NUMTOBINARY( -100, 64 ), "NTOC( -100, 2, 54, '0' ):", NTOC( -100, 2, 64, "0" )
 

Image
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10248
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: Funcion I2BIN(n)

Postby xmanuel » Sun Jun 17, 2018 11:17 am

Ahora me gusta más, pero podríamos mejorarla una miaja más jajaja :roll: :roll: :roll:
Harbour tiene la función "hb_parnidef" con lo que nos evitaríamos tener que leer dos veces la pila y "hb_retclen_buffer" que evita hacer dos copias de cRet y además harbour se encarga de liberar la memoria cuando reutilice el item stack de la pila...

Code: Select all  Expand view

    #pragma BEGINDUMP

    #include <windows.h>
    #include <hbapi.h>

    HB_FUNC( NUMTOBINARY )
    {
       HB_LONG n = hb_parnl( 1 );
       HB_INT i, digits = hb_parnidef( 2, 16 );
       char * cRet;

       digits = ( digits > 64 ? 64 : ( digits < 1 ? 1 : digits ) );
       cRet  = hb_xgrab( digits + 1 );

       for ( i = digits - 1 ; i > 0; i-- )
       {
          cRet[ i ] = ( ( n & 1 ) + '0' );
          n >>= 1;
       }
   
       hb_retclen_buffer( cRet, digits );
    }

    #pragma ENDDUMP

 


Ok Mr. Rao
Gracias
______________________________________________________________________________
Sevilla - Andalucía
xmanuel
 
Posts: 756
Joined: Sun Jun 15, 2008 7:47 pm
Location: Sevilla


Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 69 guests