c++ - Is there a better way to rewrite this ugly switch and if statement combination? -


essentially have system of gamma detectors segmented 4 crystals each, in case when 2 of of crystals register hit can determine if pair perpendicular or parallel plane of reaction generating gamma-ray. in process of writing logic wound writing huge , ugly combination of switch statements in each detector checks combinations of crystal numbers (which unique across whole array of detectors , crystals). here code, including function in question.

//the parallel , perpendicular designations used in addition double //designation 90 degree detectors if diagonal scatter in detectors //then use double designation enum scattertype{single, double, triple, quadruple, parallel, perpendicular};  scattertype eventbuffer::checkdoublegamma(int det) {     int num1=evlist[cryslist[0]].crystalnum;     int num2=evlist[cryslist[1]].crystalnum;      switch(det)     {     case 10: //first of 90 degree detectors         if( (num1==40 && num2==41) || //combo 1             (num1==41 && num2==40) || //combo 1 reverse             (num1==42 && num2==43) || //combo 2             (num1==43 && num2==42)   )//combo 2 reverse         { return parallel; }         else if( (num1==40 && num2==42) || //combo 1                  (num1==42 && num2==40) || //combo 1 reverse                  (num1==41 && num2==43) || //combo 2                  (num1==43 && num2==41)   )//combo 2 reverse         { return perpendicular; }         else         { return double;}         break;     case 11: //second of 90 degree detectors         if( (num1==44 && num2==45) || //combo 1             (num1==45 && num2==44) || //combo 1 reverse             (num1==46 && num2==47) || //combo 2             (num1==47 && num2==46)   )//combo 2 reverse         { return parallel; }         else if( (num1==44 && num2==47) || //combo 1                  (num1==47 && num2==44) || //combo 1 reverse                  (num1==45 && num2==46) || //combo 2                  (num1==46 && num2==45)   )//combo 2 reverse         { return perpendicular; }         else         { return double;}         break;     case 13: //third of 90 degree detectors         if( (num1==52 && num2==53) || //combo 1             (num1==53 && num2==52) || //combo 1 reverse             (num1==54 && num2==55) || //combo 2             (num1==55 && num2==54)   )//combo 2 reverse         { return parallel; }         else if( (num1==52 && num2==55) || //combo 1                  (num1==55 && num2==52) || //combo 1 reverse                  (num1==53 && num2==54) || //combo 2                  (num1==54 && num2==53)   )//combo 2 reverse         { return perpendicular; }         else         { return double;}         break;     case 14: //fourth of 90 degree detectors         if( (num1==56 && num2==57) || //combo 1             (num1==57 && num2==56) || //combo 1 reverse             (num1==58 && num2==59) || //combo 2             (num1==59 && num2==58)   )//combo 2 reverse         { return parallel; }         else if( (num1==56 && num2==59) || //combo 1                  (num1==59 && num2==56) || //combo 1 reverse                  (num1==57 && num2==58) || //combo 2                  (num1==58 && num2==57)   )//combo 2 reverse         { return perpendicular; }         else         { return double;}         break;     default:         throw string("made default case in checkdoublegamma switch statement, wrong");         break;     } } 

i aware that, because crystal numbers global rather per detector, away switch statement , have enormous set of conditionals linked or statements, reducing things 3 control paths, 1 returning parallel, 1 returning perpendicular, , 1 returning double, instead of 12 control paths 4 of each have. wrote not thinking , in honesty, thinking it, method reduces average case number of boolean statements grind through.

i worked out how make more efficient switching on evlist[cryslist[0]].crystalnum can reduce evaluations quite bit, yielding this:

scattertype eventbuffer::checkdoublegamma() {     int crysnum = cryslist[1].crystalnum;     switch(evlist[cryslist[0]].crystalnum)     {     case 40:         if (crysnum == 41) {return parallel;}         else if (crysnum == 42) {return perpendicular;}         else {return double;}         break;     case 41:         if (crysnum == 40) {return parallel;}         else if (crysnum == 43) {return perpendicular;}         else {return double;}         break;     case 42:         if (crysnum == 43) {return parallel;}         else if (crysnum == 40) {return perpendicular;}         else {return double;}         break;     case 43:         if (crysnum == 42) {return parallel;}         else if (crysnum == 41) {return perpendicular;}         else {return double;}         break;     case 44:         if (crysnum == 45) {return parallel;}         else if (crysnum == 47) {return perpendicular;}         else {return double;}         break;     case 45:         if (crysnum == 44) {return parallel;}         else if (crysnum == 46) {return perpendicular;}         else {return double;}         break;     case 46:         if (crysnum == 47) {return parallel;}         else if (crysnum == 45) {return perpendicular;}         else {return double;}         break;     case 47:         if (crysnum == 46) {return parallel;}         else if (crysnum == 44) {return perpendicular;}         else {return double;}         break;     case 52:         if (crysnum == 53) {return parallel;}         else if (crysnum == 55) {return perpendicular;}         else {return double;}         break;     case 53:         if (crysnum == 52) {return parallel;}         else if (crysnum == 54) {return perpendicular;}         else {return double;}         break;     case 54:         if (crysnum == 55) {return parallel;}         else if (crysnum == 53) {return perpendicular;}         else {return double;}         break;     case 55:         if (crysnum == 54) {return parallel;}         else if (crysnum == 52) {return perpendicular;}         else {return double;}         break;     case 56:         if (crysnum == 57) {return parallel;}         else if (crysnum == 59) {return perpendicular;}         else {return double;}         break;     case 57:         if (crysnum == 56) {return parallel;}         else if (crysnum == 58) {return perpendicular;}         else {return double;}         break;     case 58:         if (crysnum == 59) {return parallel;}         else if (crysnum == 57) {return perpendicular;}         else {return double;}         break;     case 59:         if (crysnum == 58) {return parallel;}         else if (crysnum == 56) {return perpendicular;}         else {return double;}         break;     default:         throw string("made default case in checkdoublegamma switch statement, wrong");         break;     } } 

the question still remains though, there trick make shorter? more efficient? more readable?

thanks in advance!

i think can move simple table , away single table lookup. haven't studied conditions in detail, looks job fine:

// fill following table in advance using existing function, or hard-code  // values if know never change: scattertype hittable[60][60];   scattertype eventbuffer::checkdoublehit(int det) {     // read crystal nums once:     unsigned = evlist[crylist[0]].crystalnum;     unsigned b = evlist[crylist[1]].crystalnum;      switch(det)     {     case 10:     case 11:     case 13:      case 14:       // better safe sorry:       assert (a < 60);       assert (b < 60);       return hittable[a][b];     break;      default:         throw string("made default case in checkdoublehit switch statement, wrong");         break;     } } 

Comments

Popular posts from this blog

python - Subclassed QStyledItemDelegate ignores Stylesheet -

java - HttpClient 3.1 Connection pooling vs HttpClient 4.3.2 -

SQL: Divide the sum of values in one table with the count of rows in another -