Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Long if..else statement

Tags:

c

if-statement

How do I reduce long if..else statement such as this one?

if( strcmp( alnumToc, "log") == 0){
            ARGNUMCHECK( in, 1);
            mpfr_log( num, stack[j-1], MPFR_RNDN);
            CPYRES( 1);
        } else if( strcmp( alnumToc, "log2") == 0){
            ARGNUMCHECK( in, 1);
            mpfr_log2( num, stack[j-1], MPFR_RNDN);
            CPYRES( 1);
        } else if( strcmp( alnumToc, "log10") == 0){
            ARGNUMCHECK( in, 1);
            mpfr_log10( num, stack[j-1], MPFR_RNDN);
            CPYRES( 1);
        } else if( strcmp( alnumToc, "sqrt") == 0){
            ARGNUMCHECK( in, 1);
            mpfr_sqrt( num, stack[j-1], MPFR_RNDN);
            CPYRES( 1);
        } else if( strcmp( alnumToc, "cbrt") == 0){
            ARGNUMCHECK( in, 1);
            mpfr_cbrt( num, stack[j-1], MPFR_RNDN);
            CPYRES( 1);
        } else if( strcmp( alnumToc, "abs") == 0){
            ARGNUMCHECK( in, 1);
            mpfr_abs( num, stack[j-1], MPFR_RNDN);
            CPYRES( 1);
        } else if( strcmp( alnumToc, "sin") == 0){
            ARGNUMCHECK( in, 1);
            mpfr_sin( num, stack[j-1], MPFR_RNDN);
            CPYRES( 1);
        } else if( strcmp( alnumToc, "cos") == 0){
            ARGNUMCHECK( in, 1);
            mpfr_cos( num, stack[j-1], MPFR_RNDN);
            CPYRES( 1);
        } else if( strcmp( alnumToc, "csc") == 0){
            ARGNUMCHECK( in, 1);
            mpfr_csc( num, stack[j-1], MPFR_RNDN);
            CPYRES( 1);
        } else if( strcmp( alnumToc, "cot") == 0){
            ARGNUMCHECK( in, 1);
            mpfr_cot( num, stack[j-1], MPFR_RNDN);
            CPYRES( 1);
        } else if( strcmp( alnumToc, "acos") == 0){
            ARGNUMCHECK( in, 1);
            mpfr_acos( num, stack[j-1], MPFR_RNDN);
            CPYRES( 1);
        } else if( strcmp( alnumToc, "asin") == 0){
            ARGNUMCHECK( in, 1);
            mpfr_asin( num, stack[j-1], MPFR_RNDN);
            CPYRES( 1);
        } else if( strcmp( alnumToc, "atan") == 0){
            ARGNUMCHECK( in, 1);
            mpfr_atan( num, stack[j-1], MPFR_RNDN);
            CPYRES( 1);
        } else if( strcmp( alnumToc, "cosh") == 0){
            ARGNUMCHECK( in, 1);
            mpfr_cosh( num, stack[j-1], MPFR_RNDN);
            CPYRES( 1);
        } else if( strcmp( alnumToc, "sinh") == 0){
            ARGNUMCHECK( in, 1);
            mpfr_sinh( num, stack[j-1], MPFR_RNDN);
            CPYRES( 1);
        }

It's not just ugly but also slow. I thought of using hashtable with function pointers. Is that good solution?
Note: there will be some mpfr functions, that take more arguments, so I can't create just one macro.

like image 240
Jakub Tětek Avatar asked Dec 25 '22 07:12

Jakub Tětek


1 Answers

That is very poor code and indeed it will be very slow. It must be rewritten from scratch.

The fastest possible way is to store all string literals in a sorted array, then use bsearch to search through it. Use an array of structs where the string is the search key. You'll have to write your own comparison function for your struct type.

If you find the string you were looking for, call its corresponding function through the function pointer:

typedef struct
{
  const char*  STRING;
  func_t       action;
} my_str_thing;

const my_str_thing TABLE [N] =
{
  { "ABC", do_this},
  { "DEF", do_that},
  ...
};

A hash table would work out too, but seems needlessly complex for this specific case.

like image 87
Lundin Avatar answered Jan 08 '23 22:01

Lundin