FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour Funcion I2BIN(n)
Posts: 1344
Joined: Wed Nov 16, 2005 09:14 PM
Funcion I2BIN(n)
Posted: Fri Jun 15, 2018 09: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 (fw): Select all Collapse
? 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)
Posts: 6755
Joined: Wed Feb 15, 2012 08:25 PM
Re: Funcion I2BIN(n)
Posted: Fri Jun 15, 2018 10:08 AM
Prueba

Code (fw): Select all Collapse
   ? 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
Posts: 1344
Joined: Wed Nov 16, 2005 09:14 PM
Re: Funcion I2BIN(n)
Posted: Fri Jun 15, 2018 02: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 (fw): Select all Collapse
Replicate("0",16-Len(DecToBin (512)))+DecToBin(512)
Posts: 6755
Joined: Wed Feb 15, 2012 08:25 PM
Re: Funcion I2BIN(n)
Posted: Fri Jun 15, 2018 05:11 PM
Bien
Por el ejemplo que has puesto antes, imaginaba que tendrias que hacer algo asi
O asi
Code (fw): Select all Collapse
   ? 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
Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: Funcion I2BIN(n)
Posted: Fri Jun 15, 2018 09: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
Posts: 817
Joined: Sun Jun 15, 2008 07:47 PM
Re: Funcion I2BIN(n)
Posted: Fri Jun 15, 2018 09: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

<div class="c" id="{CB}" style="font-family: monospace;">

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 );
}
聽</div>


Espero que te valga...
______________________________________________________________________________

Sevilla - Andaluc铆a
Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: Funcion I2BIN(n)
Posted: Sat Jun 16, 2018 03: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 (fw): Select all Collapse
#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
Posts: 817
Joined: Sun Jun 15, 2008 07:47 PM
Re: Funcion I2BIN(n)
Posted: Sat Jun 16, 2018 07: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
Posts: 1344
Joined: Wed Nov 16, 2005 09:14 PM
Re: Funcion I2BIN(n)
Posted: Sat Jun 16, 2018 05:57 PM

Muchas gracias a todos!!
Habia varias opciones.. Excelente!

Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: Funcion I2BIN(n)
Posted: Sun Jun 17, 2018 04: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 (fw): Select all Collapse
#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 (fw): Select all Collapse
? "NUMTOBINARY( -100, 64 ):", NUMTOBINARY( -100, 64 ), "NTOC( -100, 2, 54, '0' ):", NTOC( -100, 2, 64, "0" )

Regards



G. N. Rao.

Hyderabad, India
Posts: 817
Joined: Sun Jun 15, 2008 07:47 PM
Re: Funcion I2BIN(n)
Posted: Sun Jun 17, 2018 11:17 AM
Ahora me gusta m谩s, pero podr铆amos mejorarla una miaja m谩s jajaja :-) :-) :-)
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 (fw): Select all Collapse
    #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

Continue the discussion