2010-09-16 38 views
8

Necesito comprobar si un determinado indicador está configurado para un número entero.Indicadores de bit a bit en Delphi

que ya sabe cómo configurar una bandera:

flags := FLAG_A or FLAG_B or FLAG_C 

Pero, ¿cómo puedo comprobar si se ha establecido un cierto bandera?

En C++ usé el operador &, pero ¿cómo funciona eso en Delphi? Estoy un poco confundido en el momento

Respuesta

3

Utiliza el operador and como lo harías en & en C++. En argumentos numéricos, es bitwise. Here are some examples de operaciones bit a bit.

+0

Pero el resultado de eso es de nuevo un entero, requiero un booleano aunque :( – Mol

+3

@Mol: Use '<> 0' o' = FLAG_A' para obtener un booleano, por ejemplo ' if (flags y FLAG_A) <> 0' luego se establece el flag. Si el flag puede tener más de un bit, use 'if (flags y FLAG_A) = FLAG_A' (porque' '> 0' solo lo probará si al menos uno de los bits del indicador está establecido, no si todos son). –

+4

@Mol, el resultado es un número entero también en C++. C++ simplemente proporciona una conversión automática de int a bool, mientras que Delphi requiere que sea explícito sobre Lo que quiere decir es que la forma habitual es comparar contra cero, pero también puede convertir su resultado en 'LongBool'. –

27

En Delphi tiene 2 opciones:

1) utiliza 'y' operador, así:

const 
    FLAG_A = 1; // 1 shl 0 
    FLAG_B = 2; // 1 shl 1 
    FLAG_C = 4; // 1 shl 2 

var 
    Flags: Integer; 

[..] 
    Flags:= FLAG_A or FLAG_C; 
    if FLAG_A and Flags <> 0 then .. // check FLAG_A is set in flags variable 

2) definir el tipo establecido:

type 
    TFlag = (FLAG_A, FLAG_B, FLAG_C); 
    TFlags = set of TFlag; 

var 
    Flags: TFlags; 

[..] 
    Flags:= [FLAG_A, FLAG_C]; 
    if FLAG_A in Flags then .. // check FLAG_A is set in flags variable 
+3

+1 para proponer conjuntos. –

+3

+1 por recordarme un desastre que ocurrió cuando un desarrollador de smarty-pants causó un gran problema esencialmente al probar: ((FLAG_A y Flags) = 1) en lugar de ((FLAG_A y Flags) <> 0) No lo hizo trabajar en absoluto! Y se coló su cambio de "impulso de rendimiento" en una de las clases base, por lo que comenzamos a tener problemas de datos sutiles en todo el sistema. –

4

por lo general utilizan este función:

// Check if the bit at ABitIndex position is 1 (true) or 0 (false) 
function IsBitSet(const AValueToCheck, ABitIndex: Integer): Boolean; 
begin 
    Result := AValueToCheck and (1 shl ABitIndex) <> 0; 
end; 

a nd setters:

// set the bit at ABitIndex position to 1 
function SetBit(const AValueToAlter, ABitIndex: Integer): Integer; 
begin 
    Result := AValueToAlter or (1 shl ABitIndex); 
end; 

// set the bit at ABitIndex position to 0 
function ResetBit(const AValueToAlter, ABitIndex: Integer): Integer; 
begin 
    Result := AValueToAlter and (not (1 shl ABitIndex)); 
end; 

Nota: no hay comprobación de rango, solo por el rendimiento. Pero fácil de agregar si necesita

+0

¿IsBitSet funciona para usted? Tuve que quitar la parte de 1 shl para que funcionara, ¿por qué cambiaste a la izquierda una vez? –

+0

@ user1803300 no funciona para usted porque su índice de bit es valor hexadecimal, no valor dicimal –