2009-12-16 3 views
0

J'écris un code qui compare 2 octets qui représentent des entiers. Je veux voir si l'octet R est avec + -10 de G. Le problème que j'ai avec le code est avec la comparaison dans le if-statment près de la fin. Les octets ne sortent jamais hors de portée, même quand ils le devraient. Je suis sûr que le problème vient de la façon dont j'ajoute/soustrais le error_range, mais je ne connais pas d'autre moyen de le faire.C: Comparer deux octets pour voir si l'un est dans une certaine plage de l'autre

J'ai d'abord considéré la conversion des octets en entiers, mais je ne trouve aucune aide avec cela en ligne. Si cela fonctionne mieux que ce que je fais ici, s'il vous plaît dites-moi comment le faire.

Toute aide est appréciée!

const char ERROR_RANGE = 0x1010; //warning: overflow in implicit constant conversion 
char R, G; /2 separate bytes 
char buffer; //enough space for 1 byte 

image = fopen(fileName,"r"); //open file 

fread(&buffer, 1, 1, image); //read 1 byte 
memcpy (&R,&buffer,1); //store it as R 

fread(&buffer, 1, 1, image); //read 1 byte 
memcpy (&G,&buffer,1); //store it as G 

fclose(image); 

if((R >= (G + ERROR_RANGE)) && (R <= (G - ERROR_RANGE))) 
{ 
    printf("Outside of range!\n"); 
} 

Merci.

+0

Utilisez unsigned char. –

+3

0x1010 == 4112 ... –

+0

Avez-vous pensé à imprimer ERROR_RANGE pour voir à quoi cela est initialisé? Aussi, qu'attendez-vous si la valeur lue dans le fichier est de 126? –

Répondre

11

Votre problème est que votre test dit:

si (R est supérieur ou égal à l'erreur G +) et (R est inférieur ou égal à G - ERREUR)

ça ne peut pas être les deux.

Remplacez le && par || dans la première instance.

Un meilleur test serait:

si (la différence de R et G est supérieure à l'erreur)

qui se traduit par:

if (abs(R - G) > ERROR_RANGE) 
{ 
    printf("Error"); 
} 
+0

WOW merci d'avoir attrapé cela. Je voulais dire ou! Et merci pour la suggestion de les soustraire! – KMM

+0

@KMM - Si j'ai des problèmes avec des instructions composées si je les écris souvent en anglais ou en pseudo-code, je trouve plus facile à repérer quand j'ai mes AND et OR à l'envers 0: – ChrisF

+1

Si vous préférez les écrire en anglais, c'est ce que iso646.h est pour. –

6

premier problème est que vous utilisez &&, et non ||. R ne va pas être à la fois trop haut et trop bas. Deuxièmement, êtes-vous sûr que R et G seront dans des limites raisonnables? Si char sur votre système est non signé, alors G - ERROR_RANGE pourrait bien être un grand nombre si G est petit, pas un petit. Vous êtes probablement mieux avec quelque chose comme if (abs(R - G) <= ERROR_RANGE).

+1

Puisque R et G sont tous les deux des octets simples, alors ils seront bien dans la fourchette raisonnable supportée par 'int' (et les valeurs sont promues 'int' avant les comparaisons ou les calculs, bien sûr - promotions normales) . –

+0

+1 pour m'avoir battu ... –

+0

@Jonathan: Merci de me le rappeler. Cependant, si char est non signé sur cette implémentation particulière (et IIRC la norme lui permet d'être non plus), ne fait-elle pas la promotion de non signé int? Dans ce cas, nous avons toujours le problème. –

2

Y at-il une raison quelconque, vous ne pouviez pas utiliser quelque chose comme:

if (abs(R-G) > ERROR_RANGE) 
    // ... 
1

Voilà mon coup de couteau à elle, NON TESTÉ:

unsigned char buffer[2]; 
int r, g, diff; 

image = fopen(fileName, "r"); 
fread(&buffer, 2, 1, image); 

r = buffer[0]; 
g = buffer[1]; 
dif = r - g; 

if (abs(dif) > 10) { printf... } 

Il utilise la fonction abs pour faire la différence toujours positive. .. plus facile de comparer de cette façon. Une légère amélioration des performances par rapport à la lecture des deux premiers octets en une fois. Assigner les caractères (non signés) aux entiers les rendra facilement comparables.

3

En dehors de ce qui a déjà été dit ...

La valeur 0x1010 est trop grand pour tenir dans un octet, et deux octets ne peut jamais être différent de plus de 255 (0xff). Vouliez-vous dire 1010 binaire (== 10 décimal == 0xA hex)?

En outre, il n'y a pas besoin de lire et de copier, vous pouvez simplement lire dans vos variables directement:

fread(&R, 1, 1, image); //read 1 byte 
fread(&G, 1, 1, image); //read 1 byte 
+0

Oui, je voulais dire 10 en décimal. Merci beaucoup. – KMM

+0

+1 pour deviner la confusion binaire vs hex. –

Questions connexes