C: realizar la comparación de las variables firmado sin firmar y sin colada
-
28-09-2019 - |
Pregunta
Quiero una función con la firma siguiente:
bool signed_a_greater_than_signed_b(unsigned char a, unsigned char b);
su salida debe ser 1
si y sólo si la vista de complemento a 2 de los bits almacenados en a
es mayor que vista el complemento a 2 de los bits almacenados en b
. de lo contrario la salida debe ser 0
. por ejemplo:
signed_a_greater_than_signed_b(0b10000000,any number) => 0
signed_a_greater_than_signed_b(0b01111111,any number other than 0b01111111) => 1
signed_a_greater_than_signed_b(0b00000000,0b00000001) => 0
signed_a_greater_than_signed_b(0b00000000,0b11111111) => 1
signed_a_greater_than_signed_b(0b00000000,0b00000000) => 0
es la función no tener ninguna conversión implícita / explícita ??strong> (ya que estas son las conversiones definido por la implementación, y por lo tanto no es portátil)
una tal aplicación es:
bool signed_a_greater_than_signed_b(unsigned char a, unsigned char b)
{
// if 'signed' a is positive then
// return 1 if a is greater than b or b is negative
// otherwise, if 'signed' a is negative then
// return 1 if a is greater than b and b is negative
if (a <= 0b01111111) return ((b < a) || (b > 0x01111111));
else return ((b < a) && (b > 0x01111111));
}
puede sugerir una implementación que utiliza la aritmética en lugar de los condicionales para realizar este cálculo? puede usar una condición si es necesario
utilizando una combinación de variables de la ONU / firmado en comparaciones y la aritmética en C es una receta para el desastre. esta función es un ejemplo de cómo evitar el problema.
supongo que el montaje detrás de comparación de variables firmados es similar a la función que quiero poner en práctica (en arquitecturas que no soportan comparaciones firmados)
Solución
Suponiendo complemento a 2:
return (a^signbit) > (b^signbit);
donde signbit
es, obviamente, el MSB de la representación.
Otros consejos
se puede utilizar una condición si es necesario
Ya tiene una solución con una sola condición. ;)
A medida que le gustaría tener operaciones aritméticas en lugar de los condicionales, supongo que el objetivo es la velocidad. Y usando una tabla de consulta es incluso más rápido que la aritmética. Puesto que está utilizando 8 bits caracteres, una mirada en una significa que la tabla no Overkill: Usted ni siquiera necesita una tabla de tamaño 256x256. Un tamaño de la tabla de 256 es perfectamente adecuado almacenar un límite para cada valor de a
indicando la (s) b
valor puede tener que dar como resultado verdadero (o falso). Cada llamada a la función sólo tiene que realizar una tabla de consulta (a
-> limit
) y una comparación (limit
<> b
)