C: effectuer la comparaison signée dans les variables non signés sans coulée
-
28-09-2019 - |
Question
je veux une fonction avec la signature suivante:
bool signed_a_greater_than_signed_b(unsigned char a, unsigned char b);
sa sortie doit être 1
ssi la vue complément à 2 des bits stockés dans a
est supérieur au point de vue de 2 du complément des bits stockés dans b
. Sinon, la sortie doit être 0
. par exemple:
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
la fonction est ne pas avoir des conversions implicites / explicites (comme ces conversions sont la mise en œuvre définie, et donc pas portable)
une telle mise en œuvre est la suivante:
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));
}
pouvez-vous proposer une implémentation qui utilise l'arithmétique plutôt que conditionals pour effectuer ce calcul? vous pouvez utiliser une condition si vous devez
en utilisant une combinaison de variables d'ONU / signé dans les comparaisons et l'arithmétique dans C est une recette pour un désastre. cette fonction est un exemple de la façon de contourner le problème.
je suppose que l'ensemble derrière comparaison des variables signées est similaire à la fonction que je veux mettre en œuvre (sur des architectures qui ne supportent pas les comparaisons signées)
La solution
En supposant le complément de 2:
return (a^signbit) > (b^signbit);
où signbit
est évidemment le MSB de la représentation.
Autres conseils
vous pouvez utiliser une condition si vous devez
Vous avez déjà une solution en utilisant une seule condition. ;)
Comme vous voulez avoir des opérations arithmétiques plutôt que conditionals, je suppose que l'objectif est la vitesse. Et à l'aide d'une table de consultation est encore plus rapide que l'arithmétique. Parce que vous utilisez 8 bits de caractères, un moyen de table de consultation: pas Overkill Vous ne même pas besoin d'une table de taille 256x256. Une taille de la table de 256 est tout à fait suffisant à mémoriser une limite pour chaque valeur de a
indiquant la valeur (s) b
peut devoir conduire à vrai (ou faux). Chaque appel de fonction n'a besoin que d'effectuer consultation d'une table (a
-> limit
) et une comparaison (limit
<> b
)