| Ver tema anterior :: Ver tema siguiente |
| Autor |
Mensaje |
neg1414 Master

Registrado: 31 Ene 2007Mensajes: 284
|
Publicado: Mie 22 Nov, 2017 5:31 pm Asunto: como trabajar con bits |
|
|
Buenas..
Alguien me puede dar una idea de como implementar un array de bits (algo similar a la clase BitArray en c#)
Gracias. |
|
| Volver arriba |
|
 |
escafandra Master

Registrado: 29 Nov 2007Mensajes: 625Ubicación: Madrid - España
|
Publicado: Mie 22 Nov, 2017 9:05 pm Asunto: |
|
|
Tienes los campos de bits con los que puedes hacer un array pero no accedes a los bits cómo si fuese un array de bits.
También puedes hacer un array de Word (u otro tipo) y acceder medante arítmica de bits.
Saludos. |
|
| Volver arriba |
|
 |
neg1414 Master

Registrado: 31 Ene 2007Mensajes: 284
|
Publicado: Mie 22 Nov, 2017 9:21 pm Asunto: |
|
|
Gracias por contestar..
Realmente necesito acceder a cada bit del array, por lo cual debere utilizar aritmetica de bits, puedes ser un poco mas especifico (con un ejemplo mejor) sobre este metodo, es la primera vez que lo abordo estoy totalmente pez y necesitaria algunas indicaciones para poder empezar a trabajar.
Gracias Otra vez. |
|
| Volver arriba |
|
 |
escafandra Master

Registrado: 29 Nov 2007Mensajes: 625Ubicación: Madrid - España
|
Publicado: Mie 22 Nov, 2017 10:13 pm Asunto: |
|
|
Te voy a poner un ejemplo de capo de bits y aritmetica de bits.
| Código: | // defino un campo de 8 bits
struct MisBits{
UINT b0: 1;
UINT b1: 1;
UINT b2: 1;
UINT b3: 1;
UINT b4: 1;
UINT b5: 1;
UINT b6: 1;
UINT b7: 1;
};
void prueba()
{
// Declaro una variable de campo de bits
MisBits Bits = {0,0,0,0,0,0,0,0};
//Declaro un puntero a un WORD que apunta a los bits
WORD *B = (WORD*)&Bits;
//Dando valores con Campo de bits
Bits.b0 = 1;
Bits.b1 = 1;
// con aritmética de Bits
// Los cambiso en *B cambian también la variable Bits
*B |= 1; // pongo a 1 el bit 0
*B |= 1 << 1; // pongo a 1 el bit 1
*B &= ~0x2; // pongo a cero el bit 1
} |
Se entiende mejor el uso de campo de bits pero es más rápida la aritmética de bits.
Saludos. |
|
| Volver arriba |
|
 |
neg1414 Master

Registrado: 31 Ene 2007Mensajes: 284
|
Publicado: Mie 22 Nov, 2017 10:57 pm Asunto: |
|
|
Muchisimas Gracias por tu tiempo..
Voy a ponerme con el tema .. y si tengo alguna duda te la hago saber.
Gracias Otra vez |
|
| Volver arriba |
|
 |
neg1414 Master

Registrado: 31 Ene 2007Mensajes: 284
|
Publicado: Jue 23 Nov, 2017 8:34 am Asunto: |
|
|
Buenas...
Entiendo mas o menos el concepto (mas menos que mas), pero necesito tener un "array" de bits con un numero apriori indeterminado mucho mayor de 32, (entorno a miles).. y no se me ocurre como instanciarlo y mucho menos como acceder a un Bit determinado (por ejemplo el 1000)..
Es Posible Hacerlo.
Gracias. |
|
| Volver arriba |
|
 |
escafandra Master

Registrado: 29 Nov 2007Mensajes: 625Ubicación: Madrid - España
|
Publicado: Jue 23 Nov, 2017 12:38 pm Asunto: |
|
|
| neg1414 escribió: | Buenas...
Entiendo mas o menos el concepto (mas menos que mas), pero necesito tener un "array" de bits con un numero apriori indeterminado mucho mayor de 32, (entorno a miles).. y no se me ocurre como instanciarlo y mucho menos como acceder a un Bit determinado (por ejemplo el 1000)..
Es Posible Hacerlo.
Gracias. |
Es posible hacerlo. Haz un array de Bytes cada elemento es asimilable a un campo de bits de 8 bits (como te puse en el ejemplo). Ahora para acceder a un bit, accede al byte que lo contiene y desde el campo de bit (o aritmetica binaria) accedes.
Puedes crearte una clase que haga ese trabajo sobrecargando el operador [] o una función para acceder al bit. El bit que pretendes será el resto de la división entre su supuesto indice en el array y 8 (n = Index%8 y el byte será el cociente Index/8.
Te pongo un ejemplo con aritmética de bits de como leer un bit o escribirlo.
| Código: |
int GetBit(int Index, BYTE* Array)
{
return (Array[Index/8] >> Index % 8) & 1;
}
void SetBit(int Index, BYTE* Array, int Val)
{
// Val debe valer 1 ó 0
Array[Index/8] &= ~(1 << Index % 8); // Pongo el bit a 0
Array[Index/8] |= Val << Index % 8; // Pongo el valor
}
|
Saludos. |
|
| Volver arriba |
|
 |
neg1414 Master

Registrado: 31 Ene 2007Mensajes: 284
|
Publicado: Jue 23 Nov, 2017 7:15 pm Asunto: |
|
|
Buenas..
Buscado informacion sobre trabajar con bits, e dado con la clase BitSet, en principio creo que cubriria mis expectativas al ser un contenedor para almacenar bits.
Me pongo manos a la obra...
......
| Código: | #include <bitset.h>
bitset <1000> Bits;
Bits.reset; //Pongo todos los bits a 0
|
hasta aqui todo correcto
pero al realizar la siguiente operacion :
| Código: | if(!Bits[10])
{
......
} |
todo mi gozo en un pozo... al compilar salta este mensaje de error
array must have at least one element
alguna idea o me resigno y me adentro definitivamente en la aritmetica de bits..
Gracias |
|
| Volver arriba |
|
 |
_Leo Site Admin

Registrado: 11 Ago 2002Mensajes: 1875Ubicación: Lanzarote - Islas Canarias (España)
|
Publicado: Jue 23 Nov, 2017 8:16 pm Asunto: |
|
|
Debes de tener el error en otro lugar, ya que esto funciona perfectamente. ¿Supongo que estas usando BCB6?
| Código: | bitset<1000> Bits;
Bits.reset();
if (!Bits[10]) {
// ...
}
|
|
|
| Volver arriba |
|
 |
neg1414 Master

Registrado: 31 Ene 2007Mensajes: 284
|
Publicado: Jue 23 Nov, 2017 9:58 pm Asunto: |
|
|
Gracias por conestar..
No hay manera:
| Código: | #ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <bitset.h>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
void __fastcall Button1Click(TObject *Sender);
private: // User declarations
bitset <10000> Bits;
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif |
| Código: | //---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if(Bits[2])
{
}
} |
y me sigue saltando el mismo error. array must have at least one element
En biset_h
| Cita: | //
// Base class: general case.
//
template<size_t _Nw>
struct _Base_bitset {
typedef unsigned long _WordT;
//////me marca esta linea ////
_WordT _M_w[_Nw]; // 0 is the least significant word. |
Alguna idea, que me funcionase esta clase me haorraría dias de trabajo
Nota: uso bcb6 version 10.155 |
|
| Volver arriba |
|
 |
_Leo Site Admin

Registrado: 11 Ago 2002Mensajes: 1875Ubicación: Lanzarote - Islas Canarias (España)
|
Publicado: Jue 23 Nov, 2017 10:32 pm Asunto: |
|
|
A mí eso mismo me compila sin problema, lo tengo actualizado a la 10.166, creo que la última actualización que salió fue "upd4", que en el apartado de descargas de Embarcadero ya no la veo.
De todas formas haz la siguiente prueba a ver si así te funciona sin actualizar:
| Código: |
- Cambia: #include <bitset.h> por: #include <bitset>
- Cambia: bitset<10000> Bits; por: std::bitset<10000> Bits;
|
En caso de que siga sin funcionarte así, añade el siguiente #define:
| Código: | #define _USE_OLD_RW_STL 1
#include <bitset.h> |
Al final he encontrado online el "upd4", este incluye las actualizaciones anteriores, por lo que se pueden saltar todas las anteriores:
[Información de los cambios]
http://edn.embarcadero.com/article/29793
[Para el BCB6 Professional]
ftp://ftpd.codegear.com/devsupport/cbuilder/cb6/bcb6_eng_pro_upd4.exe
[Para el BCB6 Enterprise]
ftp://ftpd.codegear.com/devsupport/cbuilder/cb6/bcb6_eng_ent_upd4.exe
Otra opción que puedes probar si de momento no quieres actualizar es, cambiar en esa cabecera justo en la linea que te señala el error (el archivo es ....include\stl\_bitset.h)
Esto:
| Código: | _WordT _M_w[_Nw]; // 0 is the least significant word.
|
Por esto:
| Código: | #ifndef __BORLANDC__
_WordT _M_w[_Nw]; // 0 is the least significant word.
#else
_WordT _M_w[(_Nw != 0) ? _Nw : 1 ];
#endif |
(Es lo que cambia la actualización con respecto a esa cabecera) |
|
| Volver arriba |
|
 |
neg1414 Master

Registrado: 31 Ene 2007Mensajes: 284
|
Publicado: Vie 24 Nov, 2017 7:37 am Asunto: |
|
|
Muchisimas gracias Leo.
Llevo muchisimos años en este foro y aun me sorpense que tu, escafandra y otros aun sigais dedicando vuestro tiempo, y vuestros conocimientos a solucionarnos nuestras dudas, y todo ello sin recibir nada a cambio, mi mas sincero reconocimiento a todos.. sois unos cracks.
Gracias Otra vez, Un Saludo |
|
| Volver arriba |
|
 |
neg1414 Master

Registrado: 31 Ene 2007Mensajes: 284
|
Publicado: Dom 26 Nov, 2017 4:55 pm Asunto: |
|
|
Buenas..
Una penultima pregunta sobre la clase BitSet (cumple todas mis expectativas y funciona correctamente)
Para instanciar la clase, es necesario asignar una constante que indicara el tamaño del contenedor..
| Código: | bitset <const> bitarray; |
El problema que tengo es que la inicializacion del BitSet la hago en tiempo de ejecucion y el tamaño del contenedor no lo conozco a priori.. (es Variable).
¿Como puedo asignar ese Valor (variable) como constante a la hora de inicializar el contenedor Bitset, es posible?
Espero haberme explicado bien.. Gracias |
|
| Volver arriba |
|
 |
_Leo Site Admin

Registrado: 11 Ago 2002Mensajes: 1875Ubicación: Lanzarote - Islas Canarias (España)
|
Publicado: Dom 26 Nov, 2017 8:34 pm Asunto: |
|
|
| neg1414 escribió: | | Para instanciar la clase, es necesario asignar una constante que indicara el tamaño del contenedor.. |
Esa es una de las principales pegas, que "bitset" solo permite especificar el tamaño en tiempo de compilación. En la popular librería (biblioteca para los modernos 😉) BOOST, tienes "dynamic_bitset" es muy similar y una de las ventajas es que se puede especificar el tamaño en tiempo de ejecución.
En las versiones más actuales de C++Builder, BOOST ya viene incluida en la instalación, pero en el BCB6 no, así que he probado con una versión vieja, la 1.31 y ha funcionado (probablemente muchas otras cosas no funcionaran).
Esta versión la puedes descargar desde:
https://downloads.sourceforge.net/project/boost/boost/1.31.0/boost_1_31_0.zip
Descomprimelo dentro del directorio "include" donde este instalado el BCB6, de modo que quede así:
| Código: | ....Include
| ..
+ boost_1_31_0
| ..
+ boost
+ libs
(el resto no es necesario) |
Y añadelo en las opciones del proyecto:
MENU: Project -> Options... -> Directories/Conditionals - Include path: $(BCB)\Include\boost_1_31_0
Un pequeño ejemplo:
| Código: | //AÑADIMOS: #include <boost/dynamic_bitset.hpp>
// Creamos un array de 32 bits
boost::dynamic_bitset<> Bits(32); // todos a 0 por defecto
// Activamos los bits 0 y 15
Bits[0] = true;
Bits.set(15);
// Invertimos todos los bits
Bits.flip();
// Comprobamos si hay algun bit activo
if (Bits.any()) {
ShowMessage(String().sprintf(TEXT("Hay %d bits de %d activos"),
Bits.count(), Bits.size()));
}
// Muesta el array de bits en forma de cadena
std::string s;
boost::to_string(Bits, s);
ShowMessage(s.c_str());
// Mostramos el array como entero
ShowMessage(Bits.to_ulong());
// Comprobamos si el bit 15 esta a 0
if (!Bits[15]) // También podemos usar: !Bits.test(15)
ShowMessage("Bit 15 a 0");
|
|
|
| Volver arriba |
|
 |
neg1414 Master

Registrado: 31 Ene 2007Mensajes: 284
|
Publicado: Lun 27 Nov, 2017 7:29 am Asunto: |
|
|
Mchisimas gracias Leo, voy a probarlo.
Un Saludo |
|
| Volver arriba |
|
 |
|